Merge remote-tracking branch 'upstream/master' into I_WILL_FUCKING_NUKE_THIS_GODDDDAMMMNIIITTT

Conflicts:
	code/game/gamemodes/heist/heist.dm
	code/game/gamemodes/malfunction/malfunction.dm
	code/game/gamemodes/revolution/revolution.dm
	code/modules/admin/verbs/randomverbs.dm
This commit is contained in:
Tigercat2000
2015-12-03 11:03:01 -08:00
335 changed files with 5227 additions and 2863 deletions
+4 -3
View File
@@ -18,10 +18,11 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
var/list/type = list("Question","Player Complaint")
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
if(selected_type)
msg = input("Please enter your message.", "Admin Help", null, null) as text
msg = input("Please enter your message.", "Admin Help", null, null) as text|null
//clean the input msg
if(!msg) return
//clean the input msg
if(!msg)
return
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
+55 -22
View File
@@ -536,37 +536,65 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/cmd_admin_create_centcom_report()
set category = "Event"
set name = "Create Command Report"
set name = "Create Communications Report"
var/list/MsgType = list("Centcom Report","Enemy Communications")
if(!check_rights(R_SERVER|R_EVENT))
return
var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
var/customname = input(usr, "Pick a title for the report.", "Title") as text|null
if(!input)
return
if(!customname)
customname = "Nanotrasen Update"
for (var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = input
P.update_icon()
C.messagetitle.Add("[command_name()] Update")
C.messagetext.Add(P.info)
switch(alert("Should this be announced to the general population?",,"Yes","No"))
if("Yes")
command_announcement.Announce(input, customname);
if("No")
world << "\red New Nanotrasen Update available at all communication consoles."
if(type == "Enemy Communications")
if(!customname)
customname = type
world << sound('sound/AI/commandreport.ogg')
log_admin("[key_name(src)] has created a command report: [input]")
message_admins("[key_name_admin(src)] has created a command report", 1)
var/from = input(usr, "What kind of report? Example: Syndicate Communique", "From") as text|null
if(!from)
from = "Syndicate Communique"
switch(alert("Should this be announced to the general population?",,"Yes","No"))
if("Yes")
communications_announcement.Announce(input, customname, , , , from);
if("No")
world << "\red [from] available at all communications consoles."
for (var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "[from]"
P.info = input
P.update_icon()
C.messagetitle.Add("[from]")
C.messagetext.Add(P.info)
if(type == "Centcom Report")
if(!customname)
customname = "Nanotrasen Update"
switch(alert("Should this be announced to the general population?",,"Yes","No"))
if("Yes")
command_announcement.Announce(input, customname);
if("No")
world << "\red New Nanotrasen Update available at all communication consoles."
for (var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = input
P.update_icon()
C.messagetitle.Add("[command_name()] Update")
C.messagetext.Add(P.info)
//world << sound('sound/AI/commandreport.ogg')
log_admin("[key_name(src)] has created a communications report: [input]")
message_admins("[key_name_admin(src)] has created a communications report", 1)
feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in view())
set category = "Admin"
set name = "Delete"
@@ -729,13 +757,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
if(!check_rights(R_ADMIN))
src << "Only administrators may use this command."
return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
shuttle_master.emergency.request()
feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] admin-called the emergency shuttle.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] admin-called the emergency shuttle.</span>")
@@ -744,7 +772,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/admin_cancel_shuttle()
set category = "Admin"
set name = "Cancel Shuttle"
if(!check_rights(R_ADMIN)) return
if(!check_rights(R_ADMIN))
return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
if(shuttle_master.emergency.mode >= SHUTTLE_DOCKED)
@@ -760,6 +790,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Admin"
set name = "Toggle Deny Shuttle"
if (!ticker)
return
if(!check_rights(R_ADMIN))
return
+1 -1
View File
@@ -4,7 +4,7 @@
icon_state = "igniter"
materials = list(MAT_METAL=500, MAT_GLASS=50)
origin_tech = "magnets=1"
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread
/obj/item/device/assembly/igniter/New()
..()
@@ -177,7 +177,7 @@
call(src,triggerproc)(M)
/obj/effect/meatgrinder/proc/triggerrad1(mob)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
for(var/mob/O in viewers(world.view, src.loc))
s.set_up(3, 1, src)
s.start()
+4 -4
View File
@@ -22,20 +22,20 @@
M.Move(dest)
if(entersparks)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(4, 1, src)
s.start()
if(exitsparks)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(4, 1, dest)
s.start()
if(entersmoke)
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
var/datum/effect/system/harmless_smoke_spread/s = new /datum/effect/system/harmless_smoke_spread
s.set_up(4, 1, src, 0)
s.start()
if(exitsmoke)
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
var/datum/effect/system/harmless_smoke_spread/s = new /datum/effect/system/harmless_smoke_spread
s.set_up(4, 1, dest, 0)
s.start()
+21 -8
View File
@@ -1040,7 +1040,7 @@ datum/preferences
if("input")
switch(href_list["preference"])
if("name")
var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
if (!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.)
var/new_name = reject_bad_name(raw_name)
if(new_name)
@@ -1108,6 +1108,19 @@ datum/preferences
//this shouldn't happen
f_style = facial_hair_styles_list["Shaved"]
// Don't wear another species' underwear!
var/datum/sprite_accessory/S = underwear_list[underwear]
if(!(species in S.species_allowed))
underwear = random_underwear(gender, species)
S = undershirt_list[undershirt]
if(!(species in S.species_allowed))
undershirt = random_undershirt(gender, species)
S = socks_list[socks]
if(!(species in S.species_allowed))
socks = random_socks(gender, species)
//reset hair colour and skin colour
r_hair = 0//hex2num(copytext(new_hair, 2, 4))
g_hair = 0//hex2num(copytext(new_hair, 4, 6))
@@ -1156,7 +1169,7 @@ datum/preferences
var/input = "Choose your character's hair colour:"
if(species == "Machine")
input = "Choose your character's frame colour:"
var/new_hair = input(user, input, "Character Preference") as color|null
var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
if(new_hair)
r_hair = hex2num(copytext(new_hair, 2, 4))
g_hair = hex2num(copytext(new_hair, 4, 6))
@@ -1190,10 +1203,10 @@ datum/preferences
var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories
if(new_body_accessory)
body_accessory = new_body_accessory
body_accessory = (new_body_accessory == "None") ? null : new_body_accessory
if("facial")
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as color|null
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null
if(new_facial)
r_facial = hex2num(copytext(new_facial, 2, 4))
g_facial = hex2num(copytext(new_facial, 4, 6))
@@ -1255,7 +1268,7 @@ datum/preferences
socks = new_socks
if("eyes")
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", rgb(r_eyes, g_eyes, b_eyes)) as color|null
if(new_eyes)
r_eyes = hex2num(copytext(new_eyes, 2, 4))
g_eyes = hex2num(copytext(new_eyes, 4, 6))
@@ -1270,7 +1283,7 @@ datum/preferences
if("skin")
if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference") as color|null
var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(r_skin, g_skin, b_skin)) as color|null
if(new_skin)
r_skin = hex2num(copytext(new_skin, 2, 4))
g_skin = hex2num(copytext(new_skin, 4, 6))
@@ -1278,7 +1291,7 @@ datum/preferences
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null
if(new_ooccolor)
ooccolor = new_ooccolor
@@ -1423,7 +1436,7 @@ datum/preferences
UI_style = "Midnight"
if("UIcolor")
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!") as color|null
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
if(!UI_style_color_new) return
UI_style_color = UI_style_color_new
+1 -1
View File
@@ -79,7 +79,7 @@
// Wiring! How exciting.
var/datum/wires/rig/wires
var/datum/effect/effect/system/spark_spread/spark_system
var/datum/effect/system/spark_spread/spark_system
/obj/item/weapon/rig/examine()
usr << "This is \icon[src][src.name]."
@@ -132,7 +132,7 @@
for(var/turf/T in linkedholodeck)
if(prob(30))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
T.ex_act(3)
@@ -180,7 +180,7 @@
if(L.name=="Atmospheric Test Start")
spawn(20)
var/turf/T = get_turf(L)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
if(T)
@@ -229,7 +229,7 @@
if(L.name=="Atmospheric Test Start")
spawn(20)
var/turf/T = get_turf(L)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
if(T)
+1 -1
View File
@@ -15,7 +15,7 @@
//Server linked to.
var/obj/machinery/message_server/linkedServer = null
//Sparks effect - For emag
//var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
//var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread
//Messages - Saves me time if I want to change something.
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
+16 -1
View File
@@ -177,4 +177,19 @@
/obj/item/weaponcrafting/stock = 1,
/obj/item/stack/packageWrap = 5,)
tools = list(/obj/item/weapon/screwdriver)
time = 200
time = 200
/datum/table_recipe/spooky_camera
name = "Camera Obscura"
result = /obj/item/device/camera/spooky
time = 15
reqs = list(/obj/item/device/camera = 1,
/datum/reagent/holywater = 10)
parts = list(/obj/item/device/camera = 1)
/datum/table_recipe/notreallysoap
name = "Homemade Soap"
result = /obj/item/weapon/soap/ducttape
time = 100
reqs = list(/obj/item/stack/tape_roll = 1,
/datum/reagent/liquidgibs = 10)
+7 -3
View File
@@ -133,8 +133,10 @@
if("change_id")
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
if(attempt_code == access_code)
eftpos_name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") + " EFTPOS scanner"
print_reference()
var name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") as text|null
if(name)
eftpos_name = name + " EFTPOS scanner"
print_reference()
else
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
if("link_account")
@@ -147,7 +149,9 @@
else
usr << "\icon[src]<span class='warning'>Unable to connect to accounts database.</span>"
if("trans_purpose")
transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
var/purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose") as text|null
if(purpose)
transaction_purpose = purpose
if("trans_value")
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
if(try_num < 0)
+1 -1
View File
@@ -38,7 +38,7 @@
/datum/event/rogue_drone/end()
var/num_recovered = 0
for(var/mob/living/simple_animal/hostile/retaliate/malf_drone/D in drones_list)
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread()
sparks.set_up(3, 0, D.loc)
sparks.start()
D.z = 2
+1 -1
View File
@@ -28,7 +28,7 @@
R.my_atom = vent
R.add_reagent(pick(gunk), 50)
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
var/datum/effect/system/chem_smoke_spread/smoke = new
smoke.set_up(R, rand(1, 2), 0, vent, 0, silent = 1)
playsound(vent.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
smoke.start(3)
@@ -81,17 +81,17 @@
description_info = "This is a cosmetic attachment, as pipes currently do not spill their contents into the air."
//T-shaped valves
/obj/machinery/atmospherics/tvalve
/obj/machinery/atmospherics/trinary/tvalve
description_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow."
//Normal valves
/obj/machinery/atmospherics/valve
description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
/obj/machinery/atmospherics/binary/valve
description_info = "Click this to turn the valve. If red, the pipes on each end are separated. Otherwise, they are connected."
//TEG ports
/obj/machinery/atmospherics/binary/circulator
description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
the center of the machine gives an indicator of how much elecrtricity is being generated."
the center of the machine gives an indicator of how much electricity is being generated."
//Passive gates
/obj/machinery/atmospherics/binary/passive_gate
@@ -106,20 +106,20 @@
description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
//Freezers
/obj/machinery/atmospherics/unary/freezer
/obj/machinery/atmospherics/unary/cold_sink/freezer
description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
screwdriver, and then using a crowbar."
//Heaters
/obj/machinery/atmospherics/unary/heater
/obj/machinery/atmospherics/unary/heat_reservoir/heater
description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
screwdriver, and then using a crowbar."
//Gas injectors
/obj/machinery/atmospherics/unary/outlet_injector
description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
description_info = "Outputs the pipe's gas into the atmosphere, similar to an air vent. It can be controlled by a nearby atmospherics computer. \
A green light on it means it is on."
//Scrubbers
@@ -145,13 +145,13 @@
description_antag = "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open."
//Portable pumps
/obj/machinery/portable_atmospherics/powered/pump
/obj/machinery/portable_atmospherics/pump
description_info = "Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the air pump."
//Portable scrubbers
/obj/machinery/portable_atmospherics/powered/scrubber
/obj/machinery/portable_atmospherics/scrubber
description_info = "Filters the air, placing harmful gases into the internal gas container. The container can be emptied by \
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the scrubber. "
@@ -163,4 +163,4 @@
//Pipe dispensers
/obj/machinery/pipedispenser
description_info = "This can be moved by using a wrench. You will need to wrench it again when you want to use it. You can put \
excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function."
excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function."
@@ -10,7 +10,7 @@
Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \
It is advised to obtain a genetic backup before trying to drag it."
description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
description_antag = "Exposing the supermatter to oxygen or vacuum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \
Wearing radiation equipment will protect you from most of the delamination effects sans explosion."
+2 -2
View File
@@ -1,8 +1,8 @@
/mob/living/silicon/robot/drone
description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
They function similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access."
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
@@ -1,7 +1,7 @@
/obj/structure/girder
description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.<br>\
A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.<br>\
You can dismantle the grider with a wrench."
You can dismantle the girder with a wrench."
/obj/structure/girder/reinforced
description_info = "Add another sheet of plasteel to finish."
@@ -14,8 +14,8 @@
description_info = "Add a metal floor tile to build a floor on top of the lattice.<br>\
Lattices can be made by applying metal rods to a space tile."
/obj/structure/bed
/obj/structure/stool/bed
description_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.<br>\
<br>\
Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \
the buckles, instead."
the buckles, instead."
+3 -3
View File
@@ -21,7 +21,7 @@
description_antag = "This is a stealthy weapon which fires poisoned bolts at your target. When it hits someone, they will suffer a stun effect, in \
addition to toxins. The energy crossbow recharges itself slowly, and can be concealed in your pocket or bag."
/obj/item/weapon/gun/energy
/obj/item/weapon/gun/energy/gun
description_info = "This is an energy weapon. To fire the weapon, have your gun mode set to 'fire', \
then click where you want to fire. Most energy weapons can fire through windows harmlessly. To switch between stun and lethal, click the weapon \
in your hand. To recharge this weapon, use a weapon recharger."
@@ -51,7 +51,7 @@
/obj/item/weapon/gun/projectile
description_info = "This is a ballistic weapon. To fire the weapon, have your gun mode set to 'fire', \
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropiate ammo. The description \
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropriate ammo. The description \
will tell you what caliber you need."
/obj/item/weapon/gun/projectile/shotgun/pump
@@ -79,4 +79,4 @@
it can be concealed in your pocket or bag."
/obj/item/weapon/melee/cultblade
description_antag = "This sword is a powerful weapon, capable of severing limbs easily, if they are targeted. Nonbelivers are unable to use this weapon."
description_antag = "This sword is a powerful weapon, capable of severing limbs easily, if they are targeted. Nonbelievers are unable to use this weapon."
+1 -1
View File
@@ -515,7 +515,7 @@
if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens
M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!")
if(istype(M, /mob/living/simple_animal/pet/cat/Syndi))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
else //No water or didn't slip, get that fish!
+1 -1
View File
@@ -62,7 +62,7 @@
var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/burnt = new(get_turf(src))
setRegents(props, burnt)
user << "<span class='warning'>You smell burning coming from the [src]!</span>"
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() // burning things makes smoke!
var/datum/effect/system/bad_smoke_spread/smoke = new /datum/effect/system/bad_smoke_spread() // burning things makes smoke!
smoke.set_up(5, 0, src)
smoke.start()
if (prob(firechance))
+4
View File
@@ -648,6 +648,10 @@ datum/recipe/microwave/slimesandwich
)
result = /obj/item/weapon/ruinedvirusdish
/datum/recipe/microwave/mashedtaters
fruit = list("potato" = 1)
reagents = list("gravy" = 5)
result = /obj/item/weapon/reagent_containers/food/snacks/mashed_potatoes
//////////////////////////////////////////
// bs12 food port stuff
+10
View File
@@ -393,3 +393,13 @@
)
result = /obj/item/weapon/reagent_containers/food/snacks/flatbread
/datum/recipe/oven/turkey // Magic
items = list(
/obj/item/weapon/reagent_containers/food/snacks/meat,
/obj/item/weapon/reagent_containers/food/snacks/meat,
/obj/item/weapon/reagent_containers/food/snacks/meat,
/obj/item/weapon/reagent_containers/food/snacks/meat,
/obj/item/weapon/reagent_containers/food/snacks/stuffing,
/obj/item/weapon/reagent_containers/food/snacks/stuffing
)
result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/turkey
+87 -29
View File
@@ -113,7 +113,7 @@
descriptors |= "hallucinogenic"
if(reagents.has_reagent("styptic_powder"))
descriptors |= "medicinal"
if(reagents.has_reagent("gold"))
if(reagents.has_reagent("gold") || reagents.has_reagent("silver"))
descriptors |= "shiny"
if(reagents.has_reagent("lube"))
descriptors |= "slippery"
@@ -300,6 +300,9 @@
// TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z
if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0
if(!def_zone)
def_zone = check_zone(user.zone_sel.selecting)
user.lastattacked = M
M.lastattacker = user
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
@@ -311,7 +314,7 @@
var/hit = H.attacked_by(src, user, def_zone)
if(hit && hitsound)
playsound(loc, hitsound, 50, 1, -1)
return hit
//return hit
else
if(attack_verb.len)
user.visible_message("<span class='danger'>[M] has been [pick(attack_verb)] with [src] by [user]!</span>")
@@ -331,15 +334,23 @@
M.take_organ_damage(0, force)
M.updatehealth()
if(seed && seed.get_trait(TRAIT_STINGS))
if(seed && seed.get_trait(TRAIT_CARNIVOROUS))
seed.do_thorns(M, src, def_zone)
if(ishuman(M) && seed && seed.get_trait(TRAIT_STINGS))
if(!reagents || reagents.total_volume <= 0)
return
reagents.remove_any(rand(1,3))
seed.thrown_at(src,M)
seed.do_sting(M, src, def_zone)
reagents.remove_any(rand(1,3)) //use up some of the reagents at random
sleep(-1)
if(!src)
return
if(prob(35))
if(reagents && reagents.total_volume <= 0) //used-up fruit will be destroyed
if(user)
user << "<span class='danger'>\The [src] has dried out and crumbles to dust.</span>"
//user.drop_from_inventory(src)
qdel(src)
else if(prob(35)) //fruit that still has reagents has a chance of breaking each time it stings on hit
if(user)
user << "<span class='danger'>\The [src] has fallen to bits.</span>"
//user.drop_from_inventory(src)
@@ -366,44 +377,91 @@
if(src) qdel(src)
return
if(seed.kitchen_tag == "grass")
user.show_message("<span class='notice'>You make a grass tile out of \the [src]!</span>", 1)
for(var/i=0,i<2,i++)
var/obj/item/stack/tile/grass/G = new (user.loc)
G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
for (var/obj/item/stack/tile/grass/NG in user.loc)
if(G==NG)
continue
if(NG.amount>=NG.max_amount)
continue
NG.attackby(G, user)
user << "You add the newly-formed grass to the stack. It now contains [G.amount] tiles."
qdel(src)
return
if(seed.get_trait(TRAIT_SPREAD) > 0)
if(user.a_intent == I_DISARM && seed.get_trait(TRAIT_SPREAD) > 0) //Using disarm so we can tell if you want to plant or convert non-final plants
user << "<span class='notice'>You plant the [src.name].</span>"
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed)
new /obj/effect/plant(get_turf(user), src.seed)
qdel(src)
return
/*
if(seed.kitchen_tag)
if(!seed.final_form) //This isn't even my final form! (sorry, it had to be done)
switch(seed.kitchen_tag)
if("shand")
var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc)
if("comfrey")
var/obj/item/stack/medical/bruise_pack/comfrey/poultice = new /obj/item/stack/medical/bruise_pack/comfrey(user.loc)
poultice.heal_brute = potency
user << "<span class='notice'>You mash the leaves into a poultice.</span>"
qdel(src)
return
if("mtear")
var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc)
if("aloe")
var/obj/item/stack/medical/ointment/aloe/poultice = new /obj/item/stack/medical/ointment/aloe(user.loc)
poultice.heal_burn = potency
user << "<span class='notice'>You mash the petals into a poultice.</span>"
qdel(src)
return
*/
if("grass")
user.show_message("<span class='notice'>You make a grass tile out of \the [src]!</span>", 1)
for(var/i=0,i<2,i++)
var/obj/item/stack/tile/grass/G = new (user.loc)
G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
for (var/obj/item/stack/tile/grass/NG in user.loc)
if(G==NG)
continue
if(NG.amount>=NG.max_amount)
continue
NG.attackby(G, user)
user << "You add the newly-formed grass to the stack. It now contains [G.amount] tiles."
qdel(src)
return
if("sunflower")
var/obj/item/weapon/grown/sunflower/SF = new /obj/item/weapon/grown/sunflower(user.loc)
user.unEquip(src)
user.put_in_hands(SF)
qdel(src)
return
if("novaflower")
var/obj/item/weapon/grown/novaflower/NF = new /obj/item/weapon/grown/novaflower(user.loc)
if(prob(10))
user.say("PRAISE THE SUN!")
else
user << "PRAISE THE SUN!"
user.unEquip(src)
user.put_in_hands(NF)
qdel(src)
return
if("cashpod")
user << "You crack open the cash pod..."
var/value = round(seed.get_trait(TRAIT_POTENCY))
user.unEquip(src)
switch(value)
if(0)
user << "It's empty! What a waste..."
if(1 to 10)
user << "It has a space dollar inside. Woo."
new /obj/item/weapon/spacecash(get_turf(user))
if(11 to 20)
user << "It has 10 space dollars inside!"
new /obj/item/weapon/spacecash/c10(get_turf(user))
if(21 to 30)
user << "It has 20 space dollars inside! Cool!"
new /obj/item/weapon/spacecash/c20(get_turf(user))
if(31 to 40)
user << "It has 50 space dollars inside! Nice!"
new /obj/item/weapon/spacecash/c50(get_turf(user))
if(41 to 50)
user << "It has 100 space dollars inside! Sweet!"
new /obj/item/weapon/spacecash/c100(get_turf(user))
if(51 to 60)
user << "It has 200 space dollars inside! Awesome!"
new /obj/item/weapon/spacecash/c200(get_turf(user))
if(61 to 80)
user << "It has 500 space dollars inside! CHA-CHING!"
new /obj/item/weapon/spacecash/c500(get_turf(user))
else
user << "It has 1000 space dollars inside! JACKPOT!"
new /obj/item/weapon/spacecash/c1000(get_turf(user))
qdel(src)
return
/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user)
..()
@@ -84,3 +84,47 @@
throwforce = 0
throw_speed = 4
throw_range = 20
// Sunflower
/obj/item/weapon/grown/sunflower
name = "sunflower"
desc = "A large, fresh-grown sunflower. How cheery!"
icon = 'icons/obj/harvest.dmi'
icon_state = "sunflower"
item_state = "sunflower"
w_class = 2.0
throwforce = 0
throw_speed = 4
throw_range = 20
/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob)
M << "<font color='green'><b> [user] smacks you with a [name]!</font><font color='yellow'><b>FLOWER POWER<b></font>"
user << "<font color='green'> Your [name]'s </font><font color='yellow'><b>FLOWER POWER</b></font><font color='green'> strikes [M]</font>"
// Novaflower
/obj/item/weapon/grown/novaflower
name = "novaflower"
desc = "A large, fresh-grown novaflower. It seems to radiate heat."
icon = 'icons/obj/harvest.dmi'
icon_state = "novaflower"
item_state = "sunflower"
w_class = 2.0
throwforce = 0
throw_speed = 4
throw_range = 20
/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M as mob, mob/user as mob)
M << "<font color='green'>[user] smacks you with a [name]!</font><font color='yellow'><b>FLOWER POWER</b></font>"
user << "<font color='green'> Your [name]'s </font><font color='yellow'><b>FLOWER POWER</b></font><font color='green'> strikes [M]</font>"
if(istype(M, /mob/living))
M << "<span class='warning'>You are heated by the warmth of the of the [name]!</span>"
M.bodytemperature += potency/2 * TEMPERATURE_DAMAGE_COEFFICIENT
/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user as mob)
if(!user.gloves)
user << "<span class='warning'>The [name] burns your bare hand!</span>"
user.adjustFireLoss(rand(1,5))
+7 -1
View File
@@ -37,4 +37,10 @@
plantname = "amanita"
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus
plantname = "ambrosiadeus"
plantname = "ambrosiadeus"
/obj/item/weapon/reagent_containers/food/snacks/grown/aloe
plantname = "aloe"
/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey
plantname = "comfrey"
+70 -60
View File
@@ -21,7 +21,8 @@
var/kitchen_tag // Used by the reagent grinder.
var/trash_type // Garbage item produced when eaten.
var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal.
var/has_mob_product
var/preset_product
var/final_form = 1
var/modular_icon = 0 // Dictates if the product uses a modular sprite. 0 = preset, 1 = modular
var/preset_icon = "undef" // Name of the iconstate in icon/obj/harvest.dmi to use for preset sprite
// Make sure to set this to the correct icon if not using a modular sprite
@@ -93,7 +94,7 @@
var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3))
R.add_reagent(rid,injecting)
var/datum/effect/effect/system/chem_smoke_spread/S = new()
var/datum/effect/system/chem_smoke_spread/S = new()
S.attach(T)
S.set_up(R, round(get_trait(TRAIT_POTENCY)/4), 0, T)
S.start()
@@ -140,19 +141,47 @@
target.updatehealth()
// Adds reagents to a target.
/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit)
/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb)
if(!get_trait(TRAIT_STINGS))
return
if(!target_limb) //if we weren't given a target_limb, pick a random one to try stinging
target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin")
if(chems && chems.len)
var/body_coverage = HEAD|HEADCOVERSMOUTH|HEADCOVERSEYES|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
if(!target.can_inject(target, 0, target_limb)) //if a syringe can't get through, neither can the sting
return
var/protection_needed
switch(target_limb)
if("head")
protection_needed = HEAD | HEADCOVERSMOUTH | HEADCOVERSEYES
if("chest")
protection_needed = UPPER_TORSO
if("groin")
protection_needed = LOWER_TORSO
if("l_arm","r_arm")
protection_needed = ARMS
if("l_hand","r_hand")
protection_needed = HANDS
if("l_leg","r_leg")
protection_needed = LEGS
if("l_foot","r_foot")
protection_needed = FEET
for(var/obj/item/clothing/clothes in target)
if(target.l_hand == clothes|| target.r_hand == clothes)
continue
body_coverage &= ~(clothes.body_parts_covered)
protection_needed &= ~(clothes.body_parts_covered)
if((clothes.slot_flags & SLOT_HEAD) || (clothes.slot_flags & SLOT_MASK))
if(clothes.flags & HEADCOVERSEYES)
protection_needed &= ~(HEADCOVERSEYES)
if(clothes.flags & HEADCOVERSMOUTH)
protection_needed &= ~(HEADCOVERSMOUTH)
if(!protection_needed) //already got the needed protection, save some time and skip the rest of the loop
break
if(!body_coverage)
if(!protection_needed) //properly protected, good job!
return
target << "<span class='danger'>You are stung by \the [fruit]!</span>"
@@ -357,7 +386,7 @@
if(turfs.len)
// Moves the mob, causes sparks.
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, get_turf(target))
s.start()
var/turf/picked = get_turf(pick(turfs)) // Just in case...
@@ -417,56 +446,37 @@
chems = list()
if(prob(80))
chems["nutriment"] = list(rand(1,10),rand(10,20))
var/nutrient_type = rand(1,7)
switch(nutrient_type)
if(1)
chems["plantmatter"] = list(rand(1,10),rand(10,20))
if(2)
chems["nutriment"] = list(rand(1,10),rand(10,20))
if(3)
chems["protein"] = list(rand(1,10),rand(10,20))
if(4)
chems["plantmatter"] = list(rand(1,5),rand(10,20))
chems["nutriment"] = list(rand(1,5),rand(10,20))
if(5)
chems["plantmatter"] = list(rand(1,5),rand(10,20))
chems["protein"] = list(rand(1,5),rand(10,20))
if(6)
chems["protein"] = list(rand(1,5),rand(10,20))
chems["nutriment"] = list(rand(1,5),rand(10,20))
if(7)
chems["plantmatter"] = list(rand(1,3),rand(10,20))
chems["nutriment"] = list(rand(1,4),rand(10,20))
chems["protein"] = list(rand(1,3),rand(10,20))
var/additional_chems = rand(0,5)
if(additional_chems)
var/list/possible_chems = list(
"woodpulp",
"styptic_powder",
"methamphetamine",
"cryoxadone",
"blood",
"water",
"potassium",
"plasticide",
"mutationtoxin",
"amutationtoxin",
"epinephrine",
"space_drugs",
"salglu_solution",
"mercury",
"sugar",
"radium",
"mutadone",
"mannitol",
"thermite",
"sal_acid",
"atropine",
"omnizine",
"salbutamol",
"plasma",
"synaptizine",
"haloperidol",
"potass_iodide",
"mitocholide",
"toxin",
"rezadone",
"antihol",
"slimejelly",
"cyanide",
"lsd",
"morphine",
"ether"
)
for(var/x=1;x<=additional_chems;x++)
if(!possible_chems.len)
break
var/new_chem = pick(possible_chems)
possible_chems -= new_chem
chems[new_chem] = list(rand(1,10),rand(10,20))
var/new_chem = get_random_chemical(1)
if(chems.Find(new_chem))
chems[new_chem] = list(rand(2,20),rand(5,15)) //DOUBLE UP
else
chems[new_chem] = list(rand(1,10),rand(10,20))
if(prob(90))
set_trait(TRAIT_REQUIRES_NUTRIENTS,1)
@@ -641,8 +651,8 @@
consume_gasses |= new_gasses
gene.values["[TRAIT_CONSUME_GASSES]"] = null
if(GENE_METABOLISM)
has_mob_product = gene.values["mob_product"]
gene.values["mob_product"] = null
preset_product = gene.values["alt_product"]
gene.values["alt_product"] = null
for(var/trait in gene.values)
set_trait(trait,gene.values["[trait]"])
@@ -671,7 +681,7 @@
if(GENE_HARDINESS)
traits_to_copy = list(TRAIT_TOXINS_TOLERANCE,TRAIT_PEST_TOLERANCE,TRAIT_WEED_TOLERANCE,TRAIT_ENDURANCE)
if(GENE_METABOLISM)
P.values["mob_product"] = has_mob_product
P.values["alt_product"] = preset_product
traits_to_copy = list(TRAIT_REQUIRES_NUTRIENTS,TRAIT_REQUIRES_WATER,TRAIT_ALTER_TEMP)
if(GENE_VIGOUR)
traits_to_copy = list(TRAIT_PRODUCTION,TRAIT_MATURATION,TRAIT_YIELD,TRAIT_SPREAD)
@@ -731,14 +741,13 @@
currently_querying = list()
for(var/i = 0;i<total_yield;i++)
var/obj/item/product
if(has_mob_product)
product = new has_mob_product(get_turf(user),name)
if(preset_product)
product = new preset_product(get_turf(user),name)
else
product = new /obj/item/weapon/reagent_containers/food/snacks/grown(get_turf(user),name)
if(get_trait(TRAIT_PRODUCT_COLOUR))
if(modular_icon == 1)
if(!has_mob_product || (has_mob_product && has_mob_product != /mob/living/simple_animal/diona))
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
if(istype(product,/obj/item/weapon/reagent_containers/food))
var/obj/item/weapon/reagent_containers/food/food = product
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
@@ -773,7 +782,8 @@
new_seed.can_self_harvest = can_self_harvest
new_seed.kitchen_tag = kitchen_tag
new_seed.trash_type = trash_type
new_seed.has_mob_product = has_mob_product
new_seed.preset_product = preset_product
new_seed.final_form = final_form
//Copy over everything else.
if(mutants) new_seed.mutants = mutants.Copy()
if(chems) new_seed.chems = chems.Copy()
+71 -19
View File
@@ -206,7 +206,7 @@
display_name = "killer tomato plant"
mutants = null
can_self_harvest = 1
has_mob_product = /mob/living/simple_animal/tomato
preset_product = /mob/living/simple_animal/tomato
preset_icon = "killertomato"
/datum/seed/tomato/killer/New()
@@ -250,7 +250,7 @@
name = "eggplant"
seed_name = "eggplant"
display_name = "eggplants"
mutants = list("realeggplant")
mutants = list("egg-plant")
chems = list("plantmatter" = list(1,10))
kitchen_tag = "eggplant"
preset_icon = "eggplant"
@@ -266,6 +266,25 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#892694")
set_trait(TRAIT_PLANT_ICON,"bush4")
/datum/seed/egg_plant
name = "egg-plant"
seed_name = "egg-plant"
display_name = "egg-plants"
mutants = null
chems = list("egg" = list(1,10))
preset_product = /obj/item/weapon/reagent_containers/food/snacks/egg
/datum/seed/egg_plant/New()
..()
set_trait(TRAIT_HARVEST_REPEAT,1)
set_trait(TRAIT_MATURATION,6)
set_trait(TRAIT_PRODUCTION,6)
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_POTENCY,20)
set_trait(TRAIT_PRODUCT_ICON,"eggplant")
set_trait(TRAIT_PRODUCT_COLOUR,"#FFFFE5")
set_trait(TRAIT_PLANT_ICON,"bush4")
//Apples/varieties.
/datum/seed/apple
name = "apple"
@@ -528,7 +547,7 @@
display_name = "walking mushrooms"
mutants = null
can_self_harvest = 1
has_mob_product = /mob/living/simple_animal/hostile/mushroom
preset_product = /mob/living/simple_animal/hostile/mushroom
preset_icon = "walkingmushroom"
/datum/seed/mushroom/plump/walking/New()
@@ -696,6 +715,7 @@
display_name = "poppies"
chems = list("plantmatter" = list(1,20), "styptic_powder" = list(1,10))
kitchen_tag = "poppy"
modular_icon = 1
preset_icon = "poppy"
/datum/seed/flower/poppy/New()
@@ -715,6 +735,8 @@
mutants = list("moonflowers", "novaflowers")
display_name = "sunflowers"
preset_icon = "sunflower"
final_form = 0
kitchen_tag = "sunflower"
/datum/seed/flower/sunflower/New()
..()
@@ -730,6 +752,8 @@
mutants = null
display_name = "moonflowers"
preset_icon = "moonflower"
final_form = 1
kitchen_tag = ""
/datum/seed/flower/moonflower/New()
..()
@@ -746,6 +770,8 @@
chems = list("fuel" = list(1,10))
display_name = "novaflowers"
preset_icon = "novaflower"
final_form = 0
kitchen_tag = "novaflower"
/datum/seed/flower/novaflower/New()
..()
@@ -1104,6 +1130,7 @@
seed_name = "lemon"
display_name = "lemon trees"
chems = list("plantmatter" = list(1,20))
mutants = list("cashtree")
kitchen_tag = "lemon"
preset_icon = "lemon"
@@ -1112,6 +1139,27 @@
set_trait(TRAIT_PRODUCES_POWER,1)
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
/datum/seed/cashtree
name = "cashtree"
seed_name = "money tree"
seed_noun = "coins"
display_name = "money trees"
chems = list("gold" = list(1,10), "silver" = list(1,5))
mutants = null
final_form = 0
kitchen_tag = "cashpod"
preset_icon = "cashpod"
/datum/seed/cashtree/New()
..()
set_trait(TRAIT_MATURATION,6)
set_trait(TRAIT_PRODUCTION,6)
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_ICON,"cash")
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
set_trait(TRAIT_PLANT_ICON,"tree")
/datum/seed/citrus/orange
name = "orange"
seed_name = "orange"
@@ -1131,6 +1179,7 @@
chems = list("plantmatter" = list(1,20))
kitchen_tag = "grass"
modular_icon = 1
final_form = 0
/datum/seed/grass/New()
..()
@@ -1209,7 +1258,7 @@
seed_noun = "nodes"
display_name = "replicant pods"
can_self_harvest = 1
has_mob_product = /mob/living/simple_animal/diona
preset_product = /mob/living/simple_animal/diona
/datum/seed/diona/New()
..()
@@ -1230,7 +1279,8 @@
seed_noun = "pods"
display_name = "laughing clowns"
can_self_harvest = 1
has_mob_product = /mob/living/simple_animal/hostile/retaliate/clown
modular_icon = 1
preset_product = /mob/living/simple_animal/hostile/retaliate/clown
/datum/seed/clown/New()
..()
@@ -1244,15 +1294,16 @@
set_trait(TRAIT_PLANT_COLOUR,"#66804B")
set_trait(TRAIT_PLANT_ICON,"alien4")
/datum/seed/shand
name = "shand"
seed_name = "S'randar's hand"
display_name = "S'randar's hand leaves"
/datum/seed/comfrey
name = "comfrey"
seed_name = "comfrey"
display_name = "Comfrey"
chems = list("styptic_powder" = list(0,10))
kitchen_tag = "shand"
kitchen_tag = "comfrey"
modular_icon = 1
final_form = 0
/datum/seed/shand/New()
/datum/seed/comfrey/New()
..()
set_trait(TRAIT_MATURATION,3)
set_trait(TRAIT_PRODUCTION,5)
@@ -1263,21 +1314,22 @@
set_trait(TRAIT_PLANT_COLOUR,"#378C61")
set_trait(TRAIT_PLANT_ICON,"tree5")
/datum/seed/mtear
name = "mtear"
seed_name = "Messa's tear"
display_name = "Messa's tear leaves"
chems = list("honey" = list(1,10), "silver_sulfadiazine" = list(3,5))
kitchen_tag = "mtear"
/datum/seed/aloe
name = "aloe"
seed_name = "aloe"
display_name = "Aloe Vera"
chems = list("silver_sulfadiazine" = list(3,5))
kitchen_tag = "aloe"
modular_icon = 1
final_form = 0
/datum/seed/mtear/New()
/datum/seed/aloe/New()
..()
set_trait(TRAIT_MATURATION,3)
set_trait(TRAIT_PRODUCTION,5)
set_trait(TRAIT_YIELD,4)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_ICON,"alien4")
set_trait(TRAIT_PRODUCT_ICON,"ambrosia")
set_trait(TRAIT_PRODUCT_COLOUR,"#4CC5C7")
set_trait(TRAIT_PLANT_COLOUR,"#4CC789")
set_trait(TRAIT_PLANT_ICON,"bush7")
+4 -4
View File
@@ -101,11 +101,11 @@ var/global/list/plant_seed_sprites = list()
/obj/item/seeds/cabbageseed
seed_type = "cabbage"
/obj/item/seeds/shandseed
seed_type = "shand"
/obj/item/seeds/comfreyseed
seed_type = "comfrey"
/obj/item/seeds/mtearseed
seed_type = "mtear"
/obj/item/seeds/aloeseed
seed_type = "aloe"
/obj/item/seeds/berryseed
seed_type = "berries"
+2 -2
View File
@@ -40,12 +40,12 @@
/obj/machinery/seed_storage/garden
name = "Garden seed storage"
scanner = list("stats")
starting_seeds = list(/obj/item/seeds/appleseed = 3, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3)
starting_seeds = list(/obj/item/seeds/appleseed = 3, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/limeseed = 3, /obj/item/seeds/aloeseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/comfreyseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3)
/obj/machinery/seed_storage/xenobotany
name = "Xenobotany seed storage"
scanner = list("stats", "produce", "soil", "temperature", "light")
starting_seeds = list(/obj/item/seeds/ambrosiavulgarisseed = 3, /obj/item/seeds/appleseed = 3, /obj/item/seeds/amanitamycelium = 2, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/libertymycelium = 2, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/nettleseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plastiseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3)
starting_seeds = list(/obj/item/seeds/ambrosiavulgarisseed = 3, /obj/item/seeds/appleseed = 3, /obj/item/seeds/amanitamycelium = 2, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/libertymycelium = 2, /obj/item/seeds/limeseed = 3, /obj/item/seeds/aloeseed = 2, /obj/item/seeds/nettleseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plastiseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/comfreyseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3)
/obj/machinery/seed_storage/attack_hand(mob/user as mob)
user.set_machine(src)
@@ -125,8 +125,13 @@
max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
mature_time = world.time + seed.get_trait(TRAIT_MATURATION) + 15 //prevent vines from maturing until at least a few seconds after they've been created.
spread_chance = seed.get_trait(TRAIT_POTENCY) * 3
spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
spread_chance = seed.get_trait(TRAIT_POTENCY)
if(growth_type == 0) //These don't spread far at all (glowshroom, glowberries, brown mold)
spread_distance = round(spread_chance*0.1)
else if(growth_type == 2 || growth_type == 3) //Vines and biomass can go further than worms and mold
spread_distance = round(spread_chance*0.6)
else //Worms and mold go a moderate distance
spread_distance = round(spread_chance*0.3)
update_icon()
spawn(1) // Plants will sometimes be spawned in the turf adjacent to the one they need to end up in, for the sake of correct dir/etc being set.
@@ -17,14 +17,16 @@
// Todo, cause damage.
user_unbuckle_mob(user, user)
/obj/effect/plant/proc/trodden_on(var/mob/living/victim)
/obj/effect/plant/Crossed(var/mob/living/victim)
if(!is_mature())
return
var/mob/living/carbon/human/H = victim
if(istype(H) && H.shoes)
return
seed.do_thorns(victim,src)
seed.do_sting(victim,src,pick("r_foot","l_foot","r_leg","l_leg"))
var/target_limb = pick("r_foot","l_foot","r_leg","l_leg")
if(ishuman(victim))
var/mob/living/carbon/human/H = victim
if(H.shoes && prob(50)) //shoes will reduce chances of being stuck/stung by plants, but not always avoid it
return
seed.do_thorns(victim,src,target_limb)
seed.do_sting(victim,src,target_limb)
/obj/effect/plant/proc/entangle(var/mob/living/victim)
+4
View File
@@ -68,6 +68,8 @@
"ammonia" = 1,
"diethylamine" = 2,
"nutriment" = 1,
"protein" = 1.75,
"plantmatter" = 1.25,
"adminordrazine" = 1,
"eznutrient" = 1,
"robustharvest" = 1,
@@ -117,6 +119,8 @@
"ammonia" = list( 0.5, 0, 0 ),
"diethylamine" = list( 1, 0, 0 ),
"nutriment" = list( 0.25, 0.15, 0 ),
"protein" = list( 0.25, 0.15, 0 ),
"plantmatter" = list( 0.25, 0.15, 0 ),
"radium" = list( -1.5, 0, 0.2),
"adminordrazine" = list( 1, 1, 1 ),
"robustharvest" = list( 0, 0.2, 0 ),
Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

+3 -1
View File
@@ -51,10 +51,11 @@
/mob/living/simple_animal/hostile/panther
name = "panther"
desc = "A long sleek, black cat with sharp teeth and claws."
icon = 'code/modules/jungle/jungle.dmi'
icon = 'icons/mob/alienqueen.dmi'
icon_state = "panther"
icon_living = "panther"
icon_dead = "panther_dead"
icon_resting = "panther_rest"
icon_gib = "panther_dead"
speak_chance = 0
turns_per_move = 3
@@ -66,6 +67,7 @@
stop_automated_movement_when_pulled = 0
maxHealth = 50
health = 50
pixel_x = -16
harm_intent_damage = 8
melee_damage_lower = 15
+4 -4
View File
@@ -20,7 +20,7 @@
var/sheet_per_ore = 1
var/point_upgrade = 1
var/list/ore_values = list(("sand" = 1), ("iron" = 1), ("gold" = 20), ("silver" = 20), ("uranium" = 20), ("bananium" = 30), ("diamond" = 40), ("plasma" = 40))
var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", ("Engineering" = list("metal", "glass", "plasma")), ("Chief Engineer's Desk" = list("metal", "glass", "plasma")), ("Atmospherics" = list("metal", "glass", "plasma")))
var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"))
/obj/machinery/mineral/ore_redemption/New()
..()
@@ -67,7 +67,7 @@
stack_list[processed_sheet] = s
// Not including tg's ignoring of metal, glass being stocked because if cargo's not telling science when ores are there, they probably won't
// help with restocking metal/glass either
var/msg = "[capitalize(s.name)] sheets have been stocked in the ore reclaimer."
var/msg = "\[[worldtime2text()]\]: [capitalize(s.name)] sheets have been stocked in the ore reclaimer."
for(var/obj/machinery/requests_console/D in allConsoles)
if(D.department in src.supply_consoles)
if(supply_consoles[D.department] == null || (s.name in supply_consoles[D.department]))
@@ -242,7 +242,7 @@
return
/obj/machinery/mineral/ore_redemption/ex_act(severity, target)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(severity == 1)
@@ -410,7 +410,7 @@
qdel(voucher)
/obj/machinery/mineral/equipment_vendor/ex_act(severity, target)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(prob(50 / severity) && severity < 3)
+4 -2
View File
@@ -111,7 +111,7 @@ Works together with spawning an observer, noted above.
if(!loc) return
if(!client) return 0
regular_hud_updates()
if(client.images.len)
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud")
@@ -119,7 +119,7 @@ Works together with spawning an observer, noted above.
if(antagHUD)
var/list/target_list = list()
for(var/mob/living/target in oview(src, 14))
if(target.mind && (target.mind.special_role || issilicon(target)))
if(target.mind && (target.mind.special_role || issilicon(target) || target.mind.nation))
target_list += target
if(target_list.len)
assess_targets(target_list, src)
@@ -146,8 +146,10 @@ Works together with spawning an observer, noted above.
var/client/C = U.client
for(var/mob/living/carbon/human/target in target_list)
C.images += target.hud_list[SPECIALROLE_HUD]
C.images += target.hud_list[NATIONS_HUD]
for(var/mob/living/silicon/target in target_list)
C.images += target.hud_list[SPECIALROLE_HUD]
C.images += target.hud_list[NATIONS_HUD]
return 1
@@ -157,7 +157,7 @@
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
@@ -32,7 +32,7 @@
hgibs(loc, viruses, dna)
else
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -180,4 +180,4 @@
/mob/living/carbon/human/proc/Drain()
ChangeToHusk()
mutations |= NOCLONE
return
return
@@ -335,7 +335,7 @@
m_type = 2
if ("deathgasp")
message = "<B>[src]</B> [species.death_message]"
message = "<B>[src]</B> [species.death_message]"
m_type = 1
if ("giggle")
@@ -725,7 +725,7 @@
if(locate(/obj/item/weapon/storage/bible) in get_turf(src))
viewers(src) << "<span class='warning'><b>[src] farts on the Bible!</b></span>"
viewers(src) << "<span class='notice'><b>A mysterious force smites [src]!</b></span>"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
src.gib()
@@ -818,4 +818,4 @@
set desc = "Sets an extended description of your character's features."
set category = "IC"
flavor_text = TextPreview(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
flavor_text = TextPreview(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
+87 -76
View File
@@ -4,20 +4,21 @@
voice_name = "unknown"
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
//why are these here and not in human_defines.dm
var/list/hud_list[10]
var/datum/species/species //Contains icon generation and language information, set during New().
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna=0)
/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna = 0)
if(!dna)
dna = new /datum/dna(null)
// Species name is handled by set_species()
if(!species)
if(new_species)
set_species(new_species,1)
set_species(new_species, 1)
else
set_species()
@@ -37,6 +38,7 @@
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy")
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
..()
@@ -44,7 +46,7 @@
make_blood()
var/mob/M = src
faction |= "\ref[M]"
faction |= "\ref[M]" //what
// Set up DNA.
if(!delay_ready_dna && dna)
@@ -146,30 +148,37 @@
/mob/living/carbon/human/stok/New(var/new_loc)
..(new_loc, "Stok")
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing || buckled))
return
/mob/living/carbon/human/Bump(atom/movable/AM, yes)
if(!(yes) || now_pushing || buckled)
return 0
now_pushing = 1
if (ismob(AM))
if(ismob(AM))
var/mob/tmob = AM
if( istype(tmob, /mob/living/carbon) && prob(10) )
src.spread_disease_to(AM, "Contact")
//BubbleWrap - Should stop you pushing a restrained person out of the way
if(istype(tmob, /mob/living/carbon/human))
if(iscarbon(tmob) && prob(10))
spread_disease_to(tmob, "Contact")
//BubbleWrap - Should stop you pushing a restrained person out of the way
//i still don't get it, is this supposed to be 'bubblewrapping' or was it made by a guy named 'BubbleWrap'
if(ishuman(tmob))
for(var/mob/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
if ( !(world.time % 5) )
src << "\red [tmob] is restrained, you cannot push past"
if(tmob.pinned.len || (M.pulling == tmob && (tmob.restrained() && !M.restrained()) && M.stat == CONSCIOUS))
if(!(world.time % 5)) //tmob is pinned to wall, or is restrained and pulled by a concious unrestrained human
src << "<span class='danger'>[tmob] is restrained, you cannot push past.</span>"
now_pushing = 0
return
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
if ( !(world.time % 5) )
src << "\red [tmob] is restraining [M], you cannot push past"
return 0
//I have to fucking document this somewhere- the above if(tmob.pinned.len || etc) check above had
//locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) at the end of it
//FIRST OF ALL, THAT IS NOT HOW YOU FUCKING USE LOCATE()
//SECOND OF ALL, OH GOD, WHY WOULD YOU EVER WANT GRABBED MOBS TO BE UNABLE TO BE PUSHED PAST GOD
if(tmob.pulling == M && (M.restrained() && !tmob.restrained()) && tmob.stat == CONSCIOUS)
if(!(world.time % 5))
src << "<span class='danger'>[tmob] is restraining [M], you cannot push past.</span>"
now_pushing = 0
return
return 0
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
@@ -178,35 +187,35 @@
now_pushing = 0
return
if(istype(tmob,/mob/living/silicon/robot/drone)) //I have no idea why the hell this isn't already happening. How do mice do it?
loc = tmob.loc
now_pushing = 0
return
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
if((tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || restrained()) && tmob.canmove && canmove && !tmob.buckled && !tmob.buckled_mob) // mutual brohugs all around!
var/turf/oldloc = loc
loc = tmob.loc
tmob.loc = oldloc
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
if(slime.Victim == tmob)
slime.UpdateFeed()
return
//it might be 'bubblewrapping' given that this rhymes with 'hugboxing'
if((tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || restrained()))
if((canmove && tmob.canmove) && (!tmob.buckled && !tmob.buckled_mob))
var/turf/oldloc = loc
loc = tmob.loc
tmob.loc = oldloc
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
if(slime.Victim == tmob)
slime.UpdateFeed()
return
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(ishuman(tmob) && (FAT in tmob.mutations))
if(prob(40) && !(FAT in src.mutations))
src << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
src << "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>"
now_pushing = 0
return
if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
@@ -216,21 +225,19 @@
now_pushing = 0
spawn(0)
..()
if (!istype(AM, /atom/movable))
if(!istype(AM, /atom/movable))
return
if (!now_pushing)
if(!now_pushing)
now_pushing = 1
if (!AM.anchored)
if(!AM.anchored)
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window/full))
for(var/obj/structure/window/win in get_step(AM,t))
if(istype(AM, /obj/structure/window/full))
for(var/obj/structure/window/win in get_step(AM, t))
now_pushing = 0
return
step(AM, t)
now_pushing = 0
return
return
/mob/living/carbon/human/Stat()
..()
@@ -238,6 +245,9 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
stat(null, "Station Time: [worldtime2text()]")
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
@@ -246,11 +256,11 @@
if(timeleft > 0)
stat(null, "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]")
if (client.statpanel == "Status")
if(client.statpanel == "Status")
if(locate(/obj/item/device/assembly/health) in src)
stat(null, "Health: [health]")
if (internal)
if (!internal.air_contents)
if(internal)
if(!internal.air_contents)
qdel(internal)
else
stat("Internal Atmosphere Info", internal.name)
@@ -268,7 +278,12 @@
if(mind.changeling)
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
stat("Absorbed DNA", mind.changeling.absorbedcount)
stat(null, "Station Time: [worldtime2text()]")
if(mind.nation)
stat("Nation Name", "[mind.nation.current_name ? "[mind.nation.current_name]" : "[mind.nation.default_name]"]")
stat("Nation Leader", "[mind.nation.current_leader ? "[mind.nation.current_leader]" : "None"]")
stat("Nation Heir", "[mind.nation.heir ? "[mind.nation.heir]" : "None"]")
if(istype(loc, /obj/spacepod)) // Spacdpods!
var/obj/spacepod/S = loc
@@ -279,12 +294,13 @@
var/shielded = 0
var/b_loss = null
var/f_loss = null
switch (severity)
if (1.0)
switch(severity)
if(1)
b_loss += 500
if (!prob(getarmor(null, "bomb")))
if(!prob(getarmor(null, "bomb")))
gib()
return
return 0
else
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
throw_at(target, 200, 4)
@@ -301,13 +317,8 @@
limbs_affected -= 1
else valid_limbs -= processing_dismember
//return
// var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
//user.throw_at(target, 200, 4)
if (2.0)
if (!shielded)
if(2)
if(!shielded) //literally nothing could change shielded before this so wth
b_loss += 60
f_loss += 60
@@ -316,7 +327,7 @@
var/obj/item/organ/external/processing_dismember
var/list/valid_limbs = organs.Copy()
if (prob(getarmor(null, "bomb")))
if(prob(getarmor(null, "bomb")))
b_loss = b_loss/1.5
f_loss = f_loss/1.5
@@ -332,15 +343,15 @@
limbs_affected -= 1
else valid_limbs -= processing_dismember
if (!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
if(!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
ear_damage += 30
ear_deaf += 120
if (prob(70) && !shielded)
if(prob(70) && !shielded)
Paralyse(10)
if(3.0)
if(3)
b_loss += 30
if (prob(getarmor(null, "bomb")))
if(prob(getarmor(null, "bomb")))
b_loss = b_loss/2
else
@@ -357,10 +368,10 @@
limbs_affected -= 1
else valid_limbs -= processing_dismember
if (!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
if(!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
ear_damage += 15
ear_deaf += 60
if (prob(50) && !shielded)
if(prob(50) && !shielded)
Paralyse(10)
var/update = 0
@@ -368,19 +379,19 @@
for(var/obj/item/organ/external/temp in organs)
switch(temp.limb_name)
if("head")
update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message)
if("chest")
update |= temp.take_damage(b_loss * 0.4, f_loss * 0.4, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.4, f_loss * 0.4, used_weapon = weapon_message)
if("groin")
update |= temp.take_damage(b_loss * 0.1, f_loss * 0.1, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.1, f_loss * 0.1, used_weapon = weapon_message)
if("l_arm")
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if("r_arm")
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if("l_leg")
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if("r_leg")
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if("r_foot")
update |= temp.take_damage(b_loss * 0.025, f_loss * 0.025, used_weapon = weapon_message)
if("l_foot")
@@ -394,12 +405,12 @@
..()
/mob/living/carbon/human/blob_act()
if(stat == DEAD) return
if(stat == DEAD)
return
show_message("<span class='userdanger'>The blob attacks you!</span>")
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
return
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
@@ -505,7 +516,7 @@
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
@@ -1,51 +1,50 @@
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if(check_shields(0, M.name))
visible_message("\red <B>[M] attempted to touch [src]!</B>")
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
switch(M.a_intent)
if (I_HELP)
visible_message(text("\blue [M] caresses [src] with its scythe like arm."))
if (I_GRAB)
if(I_HELP)
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
if(I_GRAB)
grabbedby(M)
if(I_HARM)
M.do_attack_animation(src)
if (w_uniform)
if(w_uniform)
w_uniform.add_fingerprint(M)
var/damage = rand(15, 30)
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("\red <B>[M] has lunged at [src]!</B>")
visible_message("<span class='danger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("\red <B>[M] has slashed at [src]!</B>")
visible_message("<span class='danger'>[M] has slashed at [src]!</span>")
apply_damage(damage, BRUTE, affecting, armor_block)
if (damage >= 25)
visible_message("\red <B>[M] has wounded [src]!</B>")
if(damage >= 25)
visible_message("<span class='danger'>[M] has wounded [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
updatehealth()
if(I_DISARM)
M.do_attack_animation(src)
var/randn = rand(1, 100)
if (randn <= 80)
if(prob(80))
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
apply_effect(5, WEAKEN, run_armor_check(affecting, "melee"))
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has tackled down []!</B>", M, src), 1)
visible_message("<span class='danger'>[M] has tackled down [src]!</span>")
else
if (randn <= 99)
if(prob(99)) //this looks fucking stupid but it was previously 'var/randn = rand(1, 100); if(randn <= 99)'
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
drop_item()
visible_message(text("\red <B>[] disarmed []!</B>", M, src))
visible_message("<span class='danger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message(text("\red <B>[] has tried to disarm []!</B>", M, src))
return
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>")
@@ -4,26 +4,30 @@
health = 100
stat = CONSCIOUS
return
var/total_burn = 0
var/total_brute = 0
var/total_burn = 0
var/total_brute = 0
for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit
total_brute += O.brute_dam
total_brute += O.brute_dam //calculates health based on organ brute and burn
total_burn += O.burn_dam
health = 100 - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
//TODO: fix husking
if( (((100 - total_burn) < config.health_threshold_dead) && stat == DEAD))//100 only being used as the magic human max health number, feel free to change it if you add a var for it -- Urist
ChangeToHusk()
if(((100 - total_burn) < config.health_threshold_dead) && stat == DEAD) //100 is the magic human max health number
ChangeToHusk() //BECAUSE NO ONE THOUGHT TO USE LIVING/VAR/MAXHEALTH I GUESS
if(species.can_revive_by_healing)
var/obj/item/organ/brain/B = internal_organs_by_name["brain"]
if(B)
if((health >= (config.health_threshold_dead/100*75)) && stat == DEAD)
if((health >= (config.health_threshold_dead / 100 * 75)) && stat == DEAD)
update_revive()
if (stat == CONSCIOUS && (src in dead_mob_list)) //Defib fix
if(stat == CONSCIOUS && (src in dead_mob_list)) //Defib fix
update_revive()
return
/mob/living/carbon/human/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
@@ -36,7 +40,8 @@
brainloss = 0
/mob/living/carbon/human/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
@@ -49,7 +54,8 @@
brainloss = 0
/mob/living/carbon/human/getBrainLoss()
if(status_flags & GODMODE) return 0 //godmode
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
@@ -143,34 +149,39 @@
return
var/heal_prob = max(0, 80 - getCloneLoss())
var/mut_prob = min(80, getCloneLoss()+10)
if (amount > 0)
if (prob(mut_prob))
var/list/obj/item/organ/external/candidates = list()
for (var/obj/item/organ/external/O in organs)
if(O.status & ORGAN_ROBOT) continue
var/mut_prob = min(80, getCloneLoss() + 10)
if(amount > 0) //cloneloss is being added
if(prob(mut_prob))
var/list/obj/item/organ/external/candidates = list() //TYPECASTED LISTS ARE NOT A FUCKING THING WHAT THE FUCK
for(var/obj/item/organ/external/O in organs)
if(O.status & ORGAN_ROBOT)
continue
if(!(O.status & ORGAN_MUTATED))
candidates |= O
if (candidates.len)
if(candidates.len)
var/obj/item/organ/external/O = pick(candidates)
O.mutate()
src << "<span class = 'notice'>Something is not right with your [O.name]...</span>"
src << "<span class='notice'>Something is not right with your [O.name]...</span>"
O.add_autopsy_data("Mutation", amount)
return
else
if (prob(heal_prob))
for (var/obj/item/organ/external/O in organs)
if (O.status & ORGAN_MUTATED)
else //cloneloss is being subtracted
if(prob(heal_prob))
for(var/obj/item/organ/external/O in organs)
if(O.status & ORGAN_MUTATED)
O.unmutate()
src << "<span class = 'notice'>Your [O.name] is shaped normally again.</span>"
src << "<span class='notice'>Your [O.name] is shaped normally again.</span>"
return
if (getCloneLoss() < 1)
for (var/obj/item/organ/external/O in organs)
if (O.status & ORGAN_MUTATED)
if(getCloneLoss() < 1) //no cloneloss, fixes organs
for(var/obj/item/organ/external/O in organs)
if(O.status & ORGAN_MUTATED)
O.unmutate()
src << "<span class = 'notice'>Your [O.name] is shaped normally again.</span>"
hud_updateflag |= 1 << HEALTH_HUD
src << "<span class='notice'>Your [O.name] is shaped normally again.</span>"
hud_updateflag |= 1 << HEALTH_HUD //what even is this shit
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/getOxyLoss()
@@ -186,7 +197,7 @@
/mob/living/carbon/human/setOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
oxyloss = 0
oxyloss = 0 //this literally overrides three procs, excessive much?
else
..()
@@ -203,7 +214,7 @@
/mob/living/carbon/human/setToxLoss(var/amount)
if(species.flags & NO_POISON)
toxloss = 0
toxloss = 0 //this *also* overrides three procs, definately excessive
else
..()
@@ -230,7 +241,8 @@
//It automatically updates health status
/mob/living/carbon/human/heal_organ_damage(var/brute, var/burn)
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
if(!parts.len) return
if(!parts.len)
return
var/obj/item/organ/external/picked = pick(parts)
if(picked.heal_damage(brute,burn))
UpdateDamageIcon()
@@ -242,7 +254,8 @@
//It automatically updates health status
/mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0)
var/list/obj/item/organ/external/parts = get_damageable_organs()
if(!parts.len) return
if(!parts.len)
return
var/obj/item/organ/external/picked = pick(parts)
if(picked.take_damage(brute,burn,sharp,edge))
UpdateDamageIcon()
@@ -256,7 +269,7 @@
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
var/update = 0
while(parts.len && (brute>0 || burn>0) )
while(parts.len && ( brute > 0 || burn > 0) )
var/obj/item/organ/external/picked = pick(parts)
var/brute_was = picked.brute_dam
@@ -268,15 +281,19 @@
burn -= (burn_was-picked.burn_dam)
parts -= picked
updatehealth()
hud_updateflag |= 1 << HEALTH_HUD
speech_problem_flag = 1
if(update) UpdateDamageIcon()
if(update)
UpdateDamageIcon()
// damage MANY external organs, in random order
/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null)
if(status_flags & GODMODE) return //godmode
if(status_flags & GODMODE)
return //godmode
var/list/obj/item/organ/external/parts = get_damageable_organs()
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/obj/item/organ/external/picked = pick(parts)
@@ -289,9 +306,11 @@
burn -= (picked.burn_dam - burn_was)
parts -= picked
updatehealth()
hud_updateflag |= 1 << HEALTH_HUD
if(update) UpdateDamageIcon()
if(update)
UpdateDamageIcon()
////////////////////////////////////////////
@@ -302,7 +321,7 @@ This function restores the subjects blood to max.
/mob/living/carbon/human/proc/restore_blood()
if(!(species.flags & NO_BLOOD))
var/blood_volume = vessel.get_reagent_amount("blood")
vessel.add_reagent("blood",560.0-blood_volume)
vessel.add_reagent("blood", 560.0 - blood_volume)
/*
This function restores all organs.
@@ -314,47 +333,43 @@ This function restores all organs.
/mob/living/carbon/human/proc/HealDamage(zone, brute, burn)
var/obj/item/organ/external/E = get_organ(zone)
if(istype(E, /obj/item/organ/external))
if (E.heal_damage(brute, burn))
if(E.heal_damage(brute, burn))
UpdateDamageIcon()
hud_updateflag |= 1 << HEALTH_HUD
else
return 0
return
/mob/living/carbon/human/proc/get_organ(var/zone)
if(!zone) zone = "chest"
if (zone in list( "eyes", "mouth" ))
if(!zone)
zone = "chest"
if(zone in list("eyes", "mouth"))
zone = "head"
return organs_by_name[zone]
/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null)
//visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
//Handle other types of damage
if((damagetype != BRUTE) && (damagetype != BURN))
if(damagetype == HALLOSS)
if ((damage > 25 && prob(20)) || (damage > 50 && prob(60)))
emote("scream")
..(damage, damagetype, def_zone, blocked)
return 1
//Handle BRUTE and BURN damage
handle_suit_punctures(damagetype, damage)
blocked = (100-blocked)/100
if(blocked <= 0) return 0
blocked = (100 - blocked) / 100
if(blocked <= 0)
return 0
var/obj/item/organ/external/organ = null
if(isorgan(def_zone))
organ = def_zone
else
if(!def_zone) def_zone = ran_zone(def_zone)
if(!def_zone)
def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
if(!organ) return 0
if(!organ)
return 0
damage = damage * blocked
@@ -362,28 +377,33 @@ This function restores all organs.
if(BRUTE)
damageoverlaytemp = 20
if(species && species.brute_mod)
damage = damage*species.brute_mod
damage = damage * species.brute_mod
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
UpdateDamageIcon()
if(LAssailant && ishuman(LAssailant))
if(LAssailant && ishuman(LAssailant)) //superheros still get the comical hit markers
var/mob/living/carbon/human/H = LAssailant
if(H.mind && H.mind in (ticker.mode.superheroes || ticker.mode.supervillains || ticker.mode.greyshirts))
var/list/attack_bubble_recipients = list()
var/mob/living/user
for(var/mob/O in viewers(user, src))
if (O.client && !( O.blinded ))
if (O.client && !(O.blinded))
attack_bubble_recipients.Add(O.client)
spawn(0)
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
dmgIcon.pixel_x = (!lying) ? rand(-3,3) : rand(-11,12)
dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1)
//world << "x: [dmgIcon.pixel_x] AND y: [dmgIcon.pixel_y]"
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
receive_damage()
if(BURN)
damageoverlaytemp = 20
if(species && species.burn_mod)
damage = damage*species.burn_mod
damage = damage * species.burn_mod
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
UpdateDamageIcon()
@@ -477,4 +477,4 @@ emp_act
/mob/living/carbon/human/water_act(volume, temperature, source)
..()
if(temperature >= 330) bodytemperature = bodytemperature + (temperature - bodytemperature)
if(temperature <= 280) bodytemperature = bodytemperature - (bodytemperature - temperature)
if(temperature <= 280) bodytemperature = bodytemperature - (bodytemperature - temperature)
@@ -14,6 +14,10 @@
var/health_deficiency = (100 - health + staminaloss)
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
if(R.shock_reduction)
health_deficiency -= R.shock_reduction
if(health_deficiency >= 40)
tally += (health_deficiency / 25)
@@ -43,6 +47,8 @@
if(RUN in mutations)
tally = -1
if(HULK in mutations)
tally += 1
if(status_flags & IGNORESLOWDOWN) // make sure this is always at the end so we don't have ignore slowdown getting ignored itself
tally = -1
@@ -51,7 +57,7 @@
if(status_flags & GOTTAGOREALLYFAST)
tally -= 2
return (tally+config.human_delay)
return (tally + config.human_delay)
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0)
@@ -89,4 +95,4 @@
if(!has_gravity(loc))
return
var/obj/item/clothing/shoes/S = shoes
S.step_action(src)
S.step_action(src)
@@ -132,7 +132,7 @@
custom_emote(1, "drops what they were holding, their [E.name] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
+117 -127
View File
@@ -90,7 +90,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
@@ -136,6 +135,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
var/y_offset = pixel_y + rand(-1,1)
animate(src, pixel_x = pixel_x + x_offset, pixel_y = pixel_y + y_offset, time = 1)
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1)
if (disabilities & NERVOUS)
speech_problem_flag = 1
if (prob(10))
@@ -143,12 +143,38 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if (getBrainLoss() >= 60 && stat != 2)
speech_problem_flag = 1
if (prob(3))
if(prob(3))
var/list/s1 = list("IM A PONY NEEEEEEIIIIIIIIIGH",
"without oxigen blob don't evoluate?",
"CAPTAINS A COMDOM",
"[pick("", "that damn traitor")] [pick("joerge", "george", "gorge", "gdoruge")] [pick("mellens", "melons", "mwrlins")] is grifing me HAL;P!!!",
"can u give me [pick("telikesis","halk","eppilapse")]?",
"THe saiyans screwed",
"Bi is THE BEST OF BOTH WORLDS>",
"I WANNA PET TEH monkeyS",
"stop grifing me!!!!",
"SOTP IT#")
var/list/s2 = list("FUS RO DAH",
"fucking 4rries!",
"stat me",
">my face",
"roll it easy!",
"waaaaaagh!!!",
"red wonz go fasta",
"FOR TEH EMPRAH",
"lol2cat",
"dem dwarfs man, dem dwarfs",
"SPESS MAHREENS",
"hwee did eet fhor khayosss",
"lifelike texture ;_;",
"luv can bloooom",
"PACKETS!!!")
switch(pick(1,2,3))
if(1)
say(pick("IM A PONY NEEEEEEIIIIIIIIIGH", "without oxigen blob don't evoluate?", "CAPTAINS A COMDOM", "[pick("", "that damn traitor")] [pick("joerge", "george", "gorge", "gdoruge")] [pick("mellens", "melons", "mwrlins")] is grifing me HAL;P!!!", "can u give me [pick("telikesis","halk","eppilapse")]?", "THe saiyans screwed", "Bi is THE BEST OF BOTH WORLDS>", "I WANNA PET TEH monkeyS", "stop grifing me!!!!", "SOTP IT#"))
say(pick(s1))
if(2)
say(pick("FUS RO DAH","fucking 4rries!", "stat me", ">my face", "roll it easy!", "waaaaaagh!!!", "red wonz go fasta", "FOR TEH EMPRAH", "lol2cat", "dem dwarfs man, dem dwarfs", "SPESS MAHREENS", "hwee did eet fhor khayosss", "lifelike texture ;_;", "luv can bloooom", "PACKETS!!!"))
say(pick(s2))
if(3)
emote("drool")
@@ -336,27 +362,37 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
/mob/living/carbon/human/get_breath_from_internal(volume_needed) //making this call the parent would be far too complicated
var/null_internals = 0
if(internal)
if(istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
if(rig.offline && (rig.air_supply && internal == rig.air_supply))
null_internals = 1
var/null_internals = 0 //internals are invalid, therefore turn them off
var/skip_contents_check = 0 //rigsuit snowflake, oxygen tanks aren't stored inside the mob, so the 'contents.Find' check has to be skipped.
if(!(wear_mask && (wear_mask.flags & AIRTIGHT))) //not wearing mask
if(!(head && (head.flags & AIRTIGHT))) //not wearing helmet
null_internals = 1
if(!(wear_mask && wear_mask.flags & AIRTIGHT)) //if NOT (wear_mask AND wear_mask.flags CONTAIN AIRTIGHT)
if(!(head && head.flags & AIRTIGHT)) //if NOT (head AND head.flags CONTAIN AIRTIGHT)
null_internals = 1 //not wearing a mask or suitable helmet
if(null_internals)
internal = null
if(istype(back, /obj/item/weapon/rig)) //wearing a rigsuit
var/obj/item/weapon/rig/rig = back //needs to be typecasted because this doesn't use get_rig() for some reason
if(rig.offline && (rig.air_supply && internal == rig.air_supply)) //if rig IS offline AND (rig HAS air_supply AND internal IS air_supply)
null_internals = 1 //offline suits do not breath
if(internal)
if(internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if(internals)
internals.icon_state = "internal0"
else if(rig.air_supply && internal == rig.air_supply) //if rig HAS air_supply AND internal IS rig air_supply
skip_contents_check = 1 //skip contents.Find() check, the oxygen is valid even being outside of the mob
if(!contents.Find(internal) && (!skip_contents_check)) //if internal NOT IN contents AND skip_contents_check IS false
null_internals = 1 //not a rigsuit and your oxygen is gone
if(null_internals) //something wants internals gone
internal = null //so do it
if(internal) //check for hud updates every time this is called
if(internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed) //returns the valid air
else
if(internals)
internals.icon_state = "internal0"
return null
@@ -785,112 +821,67 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
return //TODO: DEFERRED
/mob/living/carbon/human/handle_regular_status_updates()
if(status_flags & GODMODE)
return 0
. = ..()
//SSD check, if a logged player is awake put them back to sleep!
if(player_logged && sleeping < 2)
sleeping = 2
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
silent = 0
else //ALIVE. LIGHTS ARE ON
if(.) //alive
if(REGEN in mutations)
if(nutrition)
if(prob(10))
var/randumb = rand(1,5)
var/randumb = rand(1, 5)
nutrition -= randumb
heal_overall_damage(randumb,randumb)
heal_overall_damage(randumb, randumb)
if(nutrition < 0)
nutrition = 0
// Sobering multiplier.
// Sober block grants quadruple the alcohol metabolism.
// var/sober_str=!(SOBER in mutations)?1:4
updatehealth() //TODO
if(!in_stasis)
handle_organs() //Optimized.
handle_organs()
handle_blood()
if(health <= config.health_threshold_dead || brain_op_stage == 4.0)
death()
blinded = 1
silent = 0
return 1
// the analgesic effect wears off slowly
//the analgesic effect wears off slowly
analgesic = max(0, analgesic - 1)
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 50) || (config.health_threshold_crit >= health) )
Paralyse(3)
/* Done by handle_breath()
if( health <= 20 && prob(1) )
spawn(0)
emote("gasp")
if(!reagents.has_reagent("epinephrine"))
adjustOxyLoss(1)*/
if(hallucination && !(species.flags & NO_DNA_RAD))
spawn handle_hallucinations()
spawn()
handle_hallucinations()
if(hallucination<=2)
if(hallucination <= 2)
hallucination = 0
halloss = 0
else
hallucination -= 2
if(halloss > 100)
src << "<span class='notice'>You're in too much pain to keep going...</span>"
for(var/mob/O in oviewers(src, null))
O.show_message("<B>[src]</B> slumps to the ground, too weak to continue fighting.", 1)
Paralyse(10)
setHalLoss(99)
if(paralysis)
blinded = 1
stat = UNCONSCIOUS
if(halloss > 0)
adjustHalLoss(-3)
else if(sleeping)
speech_problem_flag = 1
handle_dreams()
adjustStaminaLoss(-10)
adjustHalLoss(-3)
if (mind)
if(mind)
//Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of ether or similar.
if(player_logged)
sleeping = max(sleeping-1, 2)
else
sleeping = max(sleeping-1, 0)
sleeping = max(sleeping - 1, 2)
blinded = 1
stat = UNCONSCIOUS
if( prob(2) && health && !hal_crit )
spawn(0)
emote("snore")
if(mind)
if(mind.vampire)
if(istype(loc, /obj/structure/closet/coffin))
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
else if(status_flags & FAKEDEATH)
blinded = 1
stat = UNCONSCIOUS
else if(resting)
if(halloss > 0)
adjustHalLoss(-3)
//CONSCIOUS
else
stat = CONSCIOUS
if(halloss > 0)
adjustHalLoss(-1)
if(embedded_flag && !(mob_master.current_cycle % 10))
var/list/E
@@ -898,7 +889,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(!E.len)
embedded_flag = 0
//Vision
//Vision //god knows why this is here
var/obj/item/organ/vision
if(species.vision_organ)
vision = internal_organs_by_name[species.vision_organ]
@@ -907,17 +899,21 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
eye_blind = 0
blinded = 0
eye_blurry = 0
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
eye_blind = 1
blinded = 1
eye_blurry = 1
else
//blindness
if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) // Blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
blinded = 1
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
blinded = 1
@@ -925,59 +921,26 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
eye_blurry = 1
if(eye_blurry) // Blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
ear_deaf = max(ear_deaf, 1)
else if(ear_deaf) //deafness, heals slowly over time
ear_deaf = max(ear_deaf-1, 0)
ear_deaf = max(ear_deaf - 1, 0)
else if(istype(l_ear, /obj/item/clothing/ears/earmuffs) || istype(r_ear, /obj/item/clothing/ears/earmuffs)) //resting your ears with earmuffs heals ear damage faster
ear_damage = max(ear_damage-0.15, 0)
ear_damage = max(ear_damage - 0.15, 0)
ear_deaf = max(ear_deaf, 1)
else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
ear_damage = max(ear_damage-0.05, 0)
ear_damage = max(ear_damage - 0.05, 0)
//Dizziness
if(dizziness)
var/client/C = client
var/pixel_x_diff = 0
var/pixel_y_diff = 0
var/temp
var/saved_dizz = dizziness
dizziness = max(dizziness-1, 0)
if(C)
var/oldsrc = src
var/amplitude = dizziness*(sin(dizziness * 0.044 * world.time) + 1) / 70 // This shit is annoying at high strength
src = null
spawn(0)
if(C)
temp = amplitude * sin(0.008 * saved_dizz * world.time)
pixel_x_diff += temp
C.pixel_x += temp
temp = amplitude * cos(0.008 * saved_dizz * world.time)
pixel_y_diff += temp
C.pixel_y += temp
sleep(3)
if(C)
temp = amplitude * sin(0.008 * saved_dizz * world.time)
pixel_x_diff += temp
C.pixel_x += temp
temp = amplitude * cos(0.008 * saved_dizz * world.time)
pixel_y_diff += temp
C.pixel_y += temp
sleep(3)
if(C)
C.pixel_x -= pixel_x_diff
C.pixel_y -= pixel_y_diff
src = oldsrc
//Jitteryness
if(jitteriness)
do_jitter_animation(jitteriness)
//Flying
if(flying)
spawn()
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
@@ -989,9 +952,11 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
CheckStamina()
return 1
else //dead
blinded = 1
silent = 0
/mob/living/carbon/human/handle_vision()
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask)
@@ -1446,6 +1411,30 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
holder.icon_state = "hudshadowlingthrall"
hud_list[SPECIALROLE_HUD] = holder
if(hud_updateflag & 1 << NATIONS_HUD)
var/image/holder = hud_list[NATIONS_HUD]
holder.icon_state = "hudblank"
if(mind && mind.nation)
switch(mind.nation.default_name)
if("Atmosia")
holder.icon_state = "hudatmosia"
if("Brigston")
holder.icon_state = "hudbrigston"
if("Cargonia")
holder.icon_state = "hudcargonia"
if("People's Republic of Commandzakstan")
holder.icon_state = "hudcommand"
if("Servicion")
holder.icon_state = "hudservice"
if("Medistan")
holder.icon_state = "hudmedistan"
if("Scientopia")
holder.icon_state = "hudscientopia"
hud_list[NATIONS_HUD] = holder
hud_updateflag = 0
/mob/living/carbon/human/handle_silent()
@@ -1480,6 +1469,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
return
// Need this in species.
//#undef HUMAN_MAX_OXYLOSS
//#undef HUMAN_CRIT_MAX_OXYLOSS
@@ -1,7 +1,7 @@
/datum/species/shadow
name = "Shadow"
name_plural = "Shadows"
icobase = 'icons/mob/human_races/r_shadow.dmi'
deform = 'icons/mob/human_races/r_shadow.dmi'
@@ -12,7 +12,6 @@
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
has_organ = list(
"brain" = /obj/item/organ/brain
)
@@ -78,7 +78,6 @@
//Used in icon caching.
var/race_key = 0
var/icon/icon_template
var/is_small
var/show_ssd = 1
var/virus_immune
@@ -507,7 +506,7 @@
if(2) H.healths.icon_state = "health7"
if(5) H.healths.icon_state = "health0"
else
switch(H.health - ((flags & NO_PAIN) ? 0 : H.traumatic_shock) - H.staminaloss)
switch(100 - ((flags & NO_PAIN) ? 0 : H.traumatic_shock) - H.staminaloss)
if(100 to INFINITY) H.healths.icon_state = "health0"
if(80 to 100) H.healths.icon_state = "health1"
if(60 to 80) H.healths.icon_state = "health2"
@@ -53,7 +53,6 @@
heat_level_3_breathe = 1100 //Default 1000
flesh_color = "#34AF10"
reagent_tag = PROCESS_ORG
base_color = "#066000"
@@ -98,7 +97,6 @@
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -134,7 +132,6 @@
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#966464"
base_color = "#BE8264"
@@ -163,7 +160,6 @@
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR
dietflags = DIET_HERB
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
reagent_tag = PROCESS_ORG
@@ -179,7 +175,6 @@
language = "Vox-pidgin"
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too.
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -309,7 +304,6 @@
clothing_flags = HAS_SOCKS
bodyflags = FEET_CLAWS
dietflags = DIET_HERB
blood_color = "#FB9800"
reagent_tag = PROCESS_ORG
@@ -328,7 +322,6 @@
bodyflags = HAS_SKIN_COLOR
bloodflags = BLOOD_SLIME
dietflags = DIET_CARN
reagent_tag = PROCESS_ORG
//ventcrawler = 1 //ventcrawling commented out
@@ -355,7 +348,6 @@
flags = IS_WHITELISTED | HAS_LIPS | CAN_BE_FAT
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_HERB
reagent_tag = PROCESS_ORG
blood_color = "#A200FF"
@@ -368,6 +360,7 @@
C.dna.SetSEState(REMOTETALKBLOCK,0,1)
C.mutations -= REMOTE_TALK
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
C.mutations.Add(GREY)
C.update_mutations()
..()
@@ -408,7 +401,6 @@
dietflags = 0 //Diona regenerate nutrition in light, no diet necessary
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
blood_color = "#004400"
flesh_color = "#907E4A"
@@ -499,7 +491,7 @@
passive_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA_RAD
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA_RAD | NO_POISON
clothing_flags = HAS_SOCKS
bodyflags = HAS_SKIN_COLOR
dietflags = 0 //IPCs can't eat, so no diet
+2 -2
View File
@@ -296,8 +296,8 @@
if(sleeping)
handle_dreams()
adjustStaminaLoss(-10)
sleeping = max(sleeping-1, 0)
if( prob(10) && health && !hal_crit )
sleeping = max(sleeping - 1, 0)
if(prob(10) && health && !hal_crit)
spawn(0)
emote("snore")
+160 -46
View File
@@ -602,6 +602,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
Uses = 3
enhanced = 1
qdel(O)
if(istype(O,/obj/item/weapon/storage/bag))
..()
/obj/item/slime_extract/New()
..()
@@ -720,43 +722,11 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
w_class = 1
origin_tech = "biotech=4"
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
user << "<span class='warning'> The potion only works on baby slimes!</span>"
return ..()
if(M.is_adult) //Can't tame adults
user << "<span class='warning'> Only baby slimes can be tamed!</span>"
return..()
if(M.stat)
user << "<span class='warning'> The slime is dead!</span>"
return..()
if(M.mind)
user << "<span class='warning'> The slime resists!</span>"
return ..()
var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
pet.icon_state = "[M.colour] baby slime"
pet.icon_living = "[M.colour] baby slime"
pet.icon_dead = "[M.colour] baby slime dead"
pet.colour = "[M.colour]"
user <<"You feed the slime the potion, removing it's powers and calming it."
qdel(M)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
qdel(src)
/obj/item/weapon/slimepotion2
name = "advanced docility potion"
desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes"
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime.
user << "<span class='warning'> The potion only works on slimes!</span>"
return ..()
if(M.stat)
@@ -765,20 +735,107 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(M.mind)
user << "<span class='warning'> The slime resists!</span>"
return ..()
var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc)
pet.icon_state = "[M.colour] adult slime"
pet.icon_living = "[M.colour] adult slime"
pet.icon_dead = "[M.colour] baby slime dead"
pet.colour = "[M.colour]"
user <<"You feed the slime the potion, removing it's powers and calming it."
qdel(M)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if(M.is_adult)
var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc)
pet.icon_state = "[M.colour] adult slime"
pet.icon_living = "[M.colour] adult slime"
pet.icon_dead = "[M.colour] baby slime dead"
pet.colour = "[M.colour]"
qdel(M)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
qdel(src)
else
var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
pet.icon_state = "[M.colour] baby slime"
pet.icon_living = "[M.colour] baby slime"
pet.icon_dead = "[M.colour] baby slime dead"
pet.colour = "[M.colour]"
qdel(M)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
qdel(src)
user <<"You feed the slime the potion, removing it's powers and calming it."
/obj/item/weapon/sentience_potion
name = "sentience potion"
desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
origin_tech = "biotech=5"
var/list/not_interested = list()
var/being_used = 0
w_class = 1
/obj/item/weapon/sentience_potion/afterattack(mob/living/M, mob/user)
if(being_used || !ismob(M))
return
if(!isslime(M) && !isanimal(M) || M.ckey) //only works on animals that aren't player controlled
user << "<span class='warning'>[M] is already too intelligent for this to work!</span>"
return ..()
if(M.stat)
user << "<span class='warning'>[M] is dead!</span>"
return..()
user << "<span class='notice'>You offer the sentience potion to [M]...</span>"
being_used = 1
var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET)
shuffle(candidates)
var/time_passed = world.time
var/list/consenting_candidates = list()
for(var/candidate in candidates)
if(candidate in not_interested)
continue
spawn(0)
switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No"))
if("Yes")
if((world.time-time_passed)>=50 || !src)
return
consenting_candidates += candidate
if("No")
if(!src)
return
not_interested += candidate
sleep(50)
if(!src)
return
listclearnulls(consenting_candidates) //some candidates might have left during sleep(50)
if(consenting_candidates.len)
var/client/C = null
C = pick(consenting_candidates)
M.key = C.key
M.universal_speak = 1
M.faction |= "sentient"
M << "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>"
M << "<span class='userdanger'>You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost.</span>"
user << "<span class='notice'>[M] accepts the potion and suddenly becomes attentive and aware. It worked!</span>"
if(isanimal(M))
var/mob/living/simple_animal/S = M
S.master_commander = user
qdel(src)
else
user << "<span class='notice'>[M] looks interested for a moment, but then looks back down. Maybe you should try again later.</span>"
being_used = 0
..()
/obj/item/weapon/slimesteroid
@@ -786,6 +843,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will cause a slime to generate more extract."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
w_class = 1
origin_tech = "biotech=4"
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
@@ -810,6 +870,60 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will give a slime extract three uses."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle17"
w_class = 1
origin_tech = "biotech=4"
/obj/item/weapon/slimespeed
name = "slime speed potion"
desc = "A potent chemical mix that will remove the slowdown from any item."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle3"
w_class = 1
origin_tech = "biotech=4"
/obj/item/weapon/slimespeed/afterattack(obj/item/C, mob/user)
..()
if(!istype(C))
user << "<span class='warning'>The potion can only be used on items!</span>"
return
if(C.slowdown <= 0)
user << "<span class='warning'>The [C] can't be made any faster!</span>"
return..()
user <<"<span class='notice'>You slather the red gunk over the [C], making it faster.</span>"
C.color = "#FF0000"
C.slowdown = 0
qdel(src)
/obj/item/weapon/slimefireproof
name = "slime chill potion"
desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle17"
var/uses = 3
w_class = 1
origin_tech = "biotech=4"
/obj/item/weapon/slimefireproof/afterattack(obj/item/clothing/C, mob/user)
..()
if(!uses)
qdel(src)
return
if(!istype(C))
user << "<span class='warning'>The potion can only be used on clothing!</span>"
return
if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
user << "<span class='warning'>The [C] is already fireproof!</span>"
return..()
user <<"<span class='notice'>You slather the blue gunk over the [C], fireproofing it.</span>"
C.name = "fireproofed [C.name]"
C.color = "#000080"
C.max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
C.heat_protection = C.body_parts_covered
uses --
if(!uses)
qdel(src)
/obj/effect/goleRUNe
+10 -2
View File
@@ -56,7 +56,8 @@
if(client)
regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
if(get_nations_mode())
process_nations()
/mob/living/proc/handle_breathing()
return
@@ -301,4 +302,11 @@
if(!hud_used.hide_actions_toggle.moved)
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,button_number+1)
client.screen += hud_used.hide_actions_toggle
client.screen += hud_used.hide_actions_toggle
/mob/living/proc/process_nations()
if(client)
var/client/C = client
for(var/mob/living/carbon/human/H in view(src, world.view))
C.images += H.hud_list[NATIONS_HUD]
+13 -2
View File
@@ -85,9 +85,13 @@ proc/get_radio_key_from_channel(var/channel)
verb = "stammers"
speech_problem_flag = 1
if(COMIC in mutations)
if(GREY in mutations)
message = "<span class='grey'>[message]</span>"
else if(COMIC in mutations)
message = "<span class='sans'>[message]</span>"
returns[1] = message
returns[2] = verb
returns[3] = speech_problem_flag
@@ -251,7 +255,11 @@ proc/get_radio_key_from_channel(var/channel)
if(M.client)
speech_bubble_recipients.Add(M.client)
spawn(0)
flick_overlay(image('icons/mob/talk.dmi', src, "h[speech_bubble_test]",MOB_LAYER+1), speech_bubble_recipients, 30)
if(loc && !isturf(loc))
var/atom/A = loc //Non-turf, let it handle the speech bubble
A.speech_bubble("hR[speech_bubble_test]", A.loc, speech_bubble_recipients)
else //Turf, leave speech bubbles to the mob
speech_bubble("h[speech_bubble_test]", src, speech_bubble_recipients)
for(var/obj/O in listening_obj)
spawn(0)
@@ -426,3 +434,6 @@ proc/get_radio_key_from_channel(var/channel)
log_whisper("[src.name]/[src.key] : [message]")
return 1
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
flick_overlay(image('icons/mob/talk.dmi', bubble_loc, bubble_state,MOB_LAYER+1), bubble_recipients, 30)
+1
View File
@@ -183,6 +183,7 @@ var/list/ai_verbs_default = list(
hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
ai_list += src
..()
+10 -2
View File
@@ -55,7 +55,6 @@
aiRestorePowerRoutine = 0
blind.layer = 0
return
else
@@ -154,6 +153,9 @@
if (MED_HUD)
process_med_hud(src, 1, eyeobj)
if(get_nations_mode())
process_nations_ai()
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
health = 100
@@ -171,4 +173,10 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
add_ai_verbs(src)
/mob/living/silicon/ai/proc/process_nations_ai()
if(client)
var/client/C = client
for(var/mob/living/carbon/human/H in view(eyeobj, 14))
C.images += H.hud_list[NATIONS_HUD]
@@ -30,7 +30,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1
return 1
/mob/living/silicon/robot/mommi/New(loc)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -16,6 +16,7 @@
for (var/mob/M in viewers(T))
M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
qdel(src.cable)
cable = null
/mob/living/silicon/pai/updatehealth()
if(status_flags & GODMODE)
+5 -1
View File
@@ -6,7 +6,7 @@
robot_talk_understand = 0
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
small = 1
pass_flags = 1
pass_flags = PASSTABLE
density = 0
holder_type = /obj/item/weapon/holder/pai
var/network = "SS13"
@@ -512,6 +512,10 @@
src << "<span class='warning'>You are far too small to pull anything!</span>"
return
/mob/living/silicon/pai/update_canmove()
. = ..()
density = 0 //this is reset every canmove update otherwise
/mob/living/silicon/pai/examine(mob/user)
..(user)
@@ -92,8 +92,8 @@ var/global/list/default_pai_software = list()
ui.set_auto_update(1)
/mob/living/silicon/pai/Topic(href, href_list)
. = ..()
if(.) return
if(..())
return 1
if(href_list["software"])
var/soft = href_list["software"]
@@ -11,7 +11,7 @@
pass_flags = PASSTABLE
braintype = "Robot"
lawupdate = 0
density = 1
density = 0
req_access = list(access_engine, access_robotics)
local_transmit = 1
@@ -335,4 +335,8 @@
src.verbs |= silicon_subsystems
/mob/living/silicon/robot/drone/remove_robot_verbs()
src.verbs -= silicon_subsystems
src.verbs -= silicon_subsystems
/mob/living/silicon/robot/drone/update_canmove()
. = ..()
density = 0 //this is reset every canmove update otherwise
@@ -13,11 +13,11 @@
if(!O)
return 0
O.mouse_opacity = 2
O.mouse_opacity = 2
if(istype(O,/obj/item/borg/sight))
var/obj/item/borg/sight/S = O
sight_mode &= ~S.sight_mode
if(client)
client.screen -= O
contents -= O
@@ -45,6 +45,13 @@
if(activated(O))
src << "Already activated"
return
if (is_component_functioning("power cell") && cell)
if(istype(O, /obj/item/borg))
var/obj/item/borg/B = O
if(B.powerneeded)
if((cell.charge * 100 / cell.maxcharge) < B.powerneeded)
src << "Not enough power to activate [B.name]!"
return
if(!module_state_1)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_1 = O
@@ -71,6 +78,7 @@
sight_mode |= module_state_3:sight_mode
else
src << "You need to disable a module first!"
src.update_icons()
/mob/living/silicon/robot/proc/uneq_active()
uneq_module(module_active)
+89 -101
View File
@@ -13,40 +13,42 @@
process_locks()
process_queued_alarms()
/mob/living/silicon/robot/proc/clamp_values()
SetStunned(min(stunned, 30))
SetParalysis(min(paralysis, 30))
SetWeakened(min(weakened, 20))
sleeping = 0
ear_deaf = 0
adjustBruteLoss(0)
adjustToxLoss(0)
adjustOxyLoss(0)
adjustFireLoss(0)
/mob/living/silicon/robot/proc/use_power()
/mob/living/silicon/robot/proc/use_power()
if (is_component_functioning("power cell") && cell)
if(src.cell.charge <= 0)
if(module)
for(var/obj/item/borg/B in module.modules)
if(B.powerneeded)
if((cell.charge * 100 / cell.maxcharge) < B.powerneeded)
src << "Deactivating [B.name] due to lack of power!"
unEquip(B)
if(cell.charge <= 0)
uneq_all()
update_headlamp(1)
src.stat = UNCONSCIOUS
stat = UNCONSCIOUS
has_power = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.name == "actuator") // Let drained robots move, disable the rest
continue
C.consume_power()
else if (src.cell.charge <= 100)
else if(cell.charge <= 100)
uneq_all()
src.cell.use(1)
cell.use(1)
else
if(src.module_state_1)
src.cell.use(4)
if(src.module_state_2)
src.cell.use(4)
if(src.module_state_3)
src.cell.use(4)
if(module_state_1)
cell.use(4)
if(module_state_2)
cell.use(4)
if(module_state_3)
cell.use(4)
for(var/V in components)
var/datum/robot_component/C = components[V]
@@ -57,131 +59,116 @@
if(!is_component_functioning("actuator"))
Paralyse(3)
src.eye_blind = 0
src.stat = 0
eye_blind = 0
stat = 0
has_power = 1
else
uneq_all()
src.stat = UNCONSCIOUS
stat = UNCONSCIOUS
update_headlamp(1)
Paralyse(3)
/mob/living/silicon/robot/handle_regular_status_updates()
if(src.camera && !scrambledcodes)
if(src.stat == 2 || wires.IsCameraCut())
src.camera.status = 0
else
src.camera.status = 1
/mob/living/silicon/robot/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
return
health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
if(getOxyLoss() > 50) Paralyse(3)
/mob/living/silicon/robot/handle_regular_status_updates()
if(src.sleeping)
. = ..()
if(camera && !scrambledcodes)
if(stat == DEAD || wires.IsCameraCut())
camera.status = 0
else
camera.status = 1
if(getOxyLoss() > 50)
Paralyse(3)
src.sleeping--
if(src.resting)
if(sleeping)
Paralyse(3)
sleeping--
if(resting)
Weaken(5)
if(health <= config.health_threshold_dead && src.stat != 2) //die only once
death()
if(.) //alive
if(health <= config.health_threshold_dead)
death()
return
if (src.stat != 2) //Alive.
if(!istype(src,/mob/living/silicon/robot/drone))
if(!istype(src, /mob/living/silicon/robot/drone))
if(health < 50) //Gradual break down of modules as more damage is sustained
if(uneq_module(module_state_3))
src << "<span class='warning'>SYSTEM ERROR: Module 3 OFFLINE.</span>"
if(health < 0)
if(uneq_module(module_state_2))
src << "<span class='warning'>SYSTEM ERROR: Module 2 OFFLINE.</span>"
if(health < -50)
if(uneq_module(module_state_1))
src << "<span class='warning'>CRITICAL ERROR: All modules OFFLINE.</span>"
if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
src.stat = 1
if (src.stunned > 0)
AdjustStunned(-1)
if (src.weakened > 0)
AdjustWeakened(-1)
if (src.paralysis > 0)
AdjustParalysis(-1)
src.eye_blind = max(eye_blind, 1)
else
src.eye_blind = 0
if(paralysis || stunned || weakened)
stat = UNCONSCIOUS
else //Not stunned.
src.stat = 0
if(!paralysis > 0)
eye_blind = 0
else //Dead.
src.eye_blind = 1
else
stat = CONSCIOUS
if (src.stuttering) src.stuttering--
if (src.eye_blind)
src.eye_blind--
src.density = !( src.lying )
if (src.disabilities & BLIND)
src.eye_blind = max(1, eye_blind)
if (src.eye_blurry > 0)
src.eye_blurry--
src.eye_blurry = max(0, src.eye_blurry)
if (src.druggy > 0)
src.druggy--
src.druggy = max(0, src.druggy)
else //dead
eye_blind = 1
//update the state of modules and components here
if (src.stat != 0)
if(stat != CONSCIOUS)
uneq_all()
if(!is_component_functioning("radio") || src.stat == 1)
if(!is_component_functioning("radio") || stat == UNCONSCIOUS)
radio.on = 0
else
radio.on = 1
if(is_component_functioning("camera") && src.stat == 0)
src.blinded = 0
if(is_component_functioning("camera") && stat == CONSCIOUS)
blinded = 0
else
src.blinded = 1
blinded = 1
if(!is_component_functioning("actuator"))
src.Paralyse(3)
Paralyse(3)
return 1
/mob/living/silicon/robot/update_sight()
if (src.stat == 2 || src.sight_mode & BORGXRAY)
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.sight |= SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(stat == DEAD || sight_mode & BORGXRAY)
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else
src.see_in_dark = 8
if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGMESON)
src.sight |= SEE_TURFS
src.see_invisible = SEE_INVISIBLE_MINIMUM
src.see_in_dark = 1
else if (src.sight_mode & BORGTHERM)
src.sight |= SEE_MOBS
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (src.stat != 2)
src.sight &= ~SEE_MOBS
src.sight &= ~SEE_TURFS
src.sight &= ~SEE_OBJS
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
see_in_dark = 8
if(sight_mode & BORGMESON && sight_mode & BORGTHERM)
sight |= SEE_TURFS
sight |= SEE_MOBS
see_invisible = SEE_INVISIBLE_MINIMUM
else if(sight_mode & BORGMESON)
sight |= SEE_TURFS
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 1
else if(sight_mode & BORGTHERM)
sight |= SEE_MOBS
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if(stat != DEAD)
sight &= ~SEE_MOBS
sight &= ~SEE_TURFS
sight &= ~SEE_OBJS
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(see_override)
see_invisible = see_override
@@ -195,11 +182,11 @@
if(stat != DEAD)
if(health >= maxHealth)
healths.icon_state = "health0"
else if(health > maxHealth*0.5)
else if(health > maxHealth * 0.5)
healths.icon_state = "health2"
else if(health > 0)
healths.icon_state = "health3"
else if(health > -maxHealth*0.5)
else if(health > -maxHealth * 0.5)
healths.icon_state = "health4"
else if(health > -maxHealth)
healths.icon_state = "health5"
@@ -264,6 +251,7 @@
mind.special_role = "traitor"
ticker.mode.traitors += src.mind
..()
return 1
@@ -323,4 +311,4 @@
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
//Robots on fire
//Robots on fire
+56 -8
View File
@@ -59,8 +59,8 @@ var/list/robot_verbs_default = list(
var/modtype = "Default"
var/lower_mod = 0
var/jetpack = 0
var/datum/effect/effect/system/ion_trail_follow/ion_trail = null
var/datum/effect/effect/system/spark_spread/spark_system//So they can initialize sparks whenever/N
var/datum/effect/system/ion_trail_follow/ion_trail = null
var/datum/effect/system/spark_spread/spark_system//So they can initialize sparks whenever/N
var/jeton = 0
var/has_power = 1
var/weapon_lock = 0
@@ -87,7 +87,7 @@ var/list/robot_verbs_default = list(
var/obj/item/borg/sight/hud/med/healthhud = null
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -149,6 +149,7 @@ var/list/robot_verbs_default = list(
hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
scanner.Grant(src)
/mob/living/silicon/robot/proc/init(var/alien=0)
@@ -219,9 +220,13 @@ var/list/robot_verbs_default = list(
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
if(get_nations_mode())
modules = list("Peacekeeper")
if(mmi != null && mmi.alien)
modules = "Hunter"
modtype = input("Please, select a module!", "Robot", null, null) in modules
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
if(!modtype)
return
designation = modtype
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
@@ -296,6 +301,11 @@ var/list/robot_verbs_default = list(
module.channels = list("Security" = 1)
module_sprites["Combat Android"] = "droidcombat"
if("Peacekeeper")
module= new /obj/item/weapon/robot_module/peacekeeper(src)
module.channels = list()
module_sprites["Peacekeeper Android"] = "droidpeace"
if("Hunter")
updatename(module)
module = new /obj/item/weapon/robot_module/alien/hunter(src)
@@ -1000,16 +1010,17 @@ var/list/robot_verbs_default = list(
else
overlays += "ov-openpanel -c"
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
overlays += "[icon_state]-shield"
if(modtype == "Combat")
var/combat = list("Combat","Peacekeeper")
if(modtype in combat)
if (base_icon == "")
base_icon = icon_state
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
icon_state = "[base_icon]-roll"
else
icon_state = base_icon
for(var/obj/item/borg/combat/shield/S in module.modules)
if(activated(S))
overlays += "[base_icon]-shield"
if(jetpackoverlay)
overlays += "minerjetpack-[icon_state]"
@@ -1408,3 +1419,40 @@ var/list/robot_verbs_default = list(
connected_ai.connected_robots |= src
notify_ai(1)
sync()
/mob/living/silicon/robot/combat/New()
..()
module = new /obj/item/weapon/robot_module/combat(src)
module.channels = list("Security" = 1)
base_icon = "droidcombat"
icon_state = "droidcombat"
modtype = "Combat"
//languages
module.add_languages(src)
//subsystems
module.add_subsystems(src)
updatename()
status_flags &= ~CANPUSH
radio.config(module.channels)
notify_ai(2)
/mob/living/silicon/robot/peacekeeper/New()
..()
module = new /obj/item/weapon/robot_module/peacekeeper(src)
base_icon = "droidpeace"
icon_state = "droidpeace"
modtype = "Peacekeeper"
//languages
module.add_languages(src)
//subsystems
module.add_subsystems(src)
updatename()
status_flags &= ~CANPUSH
notify_ai(2)
@@ -67,8 +67,14 @@
return
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
var/obj/item/borg/combat/shield/shield
if(module_state_1 && istype(module_state_1,/obj/item/borg/combat/shield))
shield = module_state_1
else if(module_state_2 && istype(module_state_2,/obj/item/borg/combat/shield))
shield = module_state_2
else if(module_state_3 && istype(module_state_3,/obj/item/borg/combat/shield))
shield = module_state_3
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
@@ -112,8 +118,14 @@
var/list/datum/robot_component/parts = get_damageable_components()
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
var/obj/item/borg/combat/shield/shield
if(module_state_1 && istype(module_state_1,/obj/item/borg/combat/shield))
shield = module_state_1
else if(module_state_2 && istype(module_state_2,/obj/item/borg/combat/shield))
shield = module_state_2
else if(module_state_3 && istype(module_state_3,/obj/item/borg/combat/shield))
shield = module_state_3
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
@@ -72,11 +72,15 @@
//Personal shielding for the combat module.
/obj/item/borg
var/powerneeded // Percentage of power remaining required to run item
/obj/item/borg/combat/shield
name = "personal shielding"
desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
powerneeded = 25
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
/obj/item/borg/combat/shield/verb/set_shield_level()
@@ -92,4 +96,5 @@
name = "mobility module"
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
icon_state = "shock"
powerneeded = 25
@@ -412,12 +412,28 @@
/obj/item/weapon/robot_module/combat/New()
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.modules += new /obj/item/weapon/gun/energy/plasmacutter(src)
src.modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair?
src.modules += new /obj/item/weapon/wrench(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
/obj/item/weapon/robot_module/peacekeeper
name = "peacekeeper robot module"
/obj/item/weapon/robot_module/peacekeeper/New()
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
src.modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.modules += new /obj/item/weapon/wrench(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
@@ -70,6 +70,8 @@
ventcrawler = 2
ranged = 1
ranged_cooldown_cap = 2
universal_speak = 0
universal_understand = 0
projectilesound = 'sound/weapons/taser2.ogg'
AIStatus = AI_OFF
var/resources = 0 //Resource points, generated by consuming metal/glass
@@ -313,21 +315,25 @@
D.pixel_x = target.pixel_x
D.pixel_y = target.pixel_y
if(do_mob(src, target, 100))
src << "<span class='info'>Dismantling complete.</span>"
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
if(target.component_parts && target.component_parts.len)
for(var/obj/item/I in target.component_parts)
I.forceMove(M.loc)
var/obj/effect/swarmer/disintegration/N = new /obj/effect/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
target.dropContents()
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
new C.circuit(get_turf(M))
qdel(target)
if(!src.Adjacent(target))
src << "<span class='info'>Error:Dismantleing aborted.</span>"
else
src << "<span class='info'>Dismantling complete.</span>"
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
if(target.component_parts && target.component_parts.len)
for(var/obj/item/I in target.component_parts)
I.forceMove(M.loc)
var/obj/effect/swarmer/disintegration/N = new /obj/effect/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
target.dropContents()
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
new C.circuit(get_turf(M))
qdel(target)
/obj/effect/swarmer //Default swarmer effect object visual feedback
@@ -669,7 +669,7 @@
//spark for no reason
if(prob(5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -677,7 +677,7 @@
..()
visible_message("<b>[src]</b> blows apart!")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
respawnable_list += src
@@ -298,6 +298,27 @@ var/global/chicken_count = 0
attacktext = "kicks"
health = 50
/mob/living/simple_animal/turkey
name = "turkey"
desc = "Benjamin Franklin would be proud."
icon_state = "turkey"
icon_living = "turkey"
icon_dead = "turkey_dead"
icon_resting = "turkey_rest"
speak = list("gobble?","gobble","GOBBLE")
speak_emote = list("gobble")
emote_see = list("struts around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat //enough to make one turkey
meat_amount = 4
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "pecks"
health = 50
/mob/living/simple_animal/goose
name = "goose"
desc = "A pretty goose. Would make a nice comforter."
@@ -5,6 +5,7 @@
icon_state = "fox"
icon_living = "fox"
icon_dead = "fox_dead"
icon_resting = "fox_rest"
speak = list("Ack-Ack","Ack-Ack-Ack-Ackawoooo","Geckers","Awoo","Tchoff")
speak_emote = list("geckers", "barks")
emote_hear = list("howls","barks")
@@ -0,0 +1,895 @@
/mob/living/simple_animal/hostile/guardian
name = "Guardian Spirit"
real_name = "Guardian Spirit"
desc = "A mysterious being that stands by it's charge, ever vigilant."
speak_emote = list("intones")
response_help = "passes through"
response_disarm = "flails at"
response_harm = "punches"
icon = 'icons/mob/mob.dmi'
icon_state = "stand"
icon_living = "stand"
speed = 0
a_intent = I_HARM
stop_automated_movement = 1
floating = 1
attack_sound = 'sound/weapons/punch1.ogg'
minbodytemp = 0
maxbodytemp = 10000000
min_oxy = 0
max_oxy = INFINITY
min_tox = 0
max_tox = INFINITY
min_co2 = 0
max_co2 = INFINITY
min_n2 = 0
max_n2 = INFINITY
attacktext = "punches"
maxHealth = 100000 //The spirit itself is invincible
health = 100000
environment_smash = 0
melee_damage_lower = 15
melee_damage_upper = 15
AIStatus = AI_OFF
var/animated_manifest = FALSE
var/cooldown = 0
var/damage_transfer = 1 //how much damage from each attack we transfer to the owner
var/mob/living/summoner
var/range = 10 //how far from the user the spirit can be
var/playstyle_string = "You are a standard Guardian. You shouldn't exist!"
var/magic_fluff_string = " You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!"
var/tech_fluff_string = "BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!"
var/bio_fluff_string = "Your scarabs fail to mutate. This shouldn't happen! Submit a bug report!"
var/admin_fluff_string = "URK URF!"//the wheels on the bus...
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
..()
if(summoner)
if(summoner.stat == DEAD)
// src << "<span class='danger'>Your summoner has died!</span>"
// visible_message("<span class='danger'><B>The [src] dies along with its user!</B></span>")
// summoner.visible_message("<span class='danger'><B>[summoner]'s body is completely consumed by the strain of sustaining [src]!</B></span>")
// for(var/obj/item/W in summoner)
// if(!summoner.unEquip(W))
// qdel(W)
//summoner.dust()
//ghostize()
//qdel(src)
//else
src << "<span class='danger'>Your summoner has died!</span>"
visible_message("<span class='danger'><B>The [src] dies along with its user!</B></span>")
ghostize()
qdel(src)
if(summoner)
if (get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
src << "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]"
visible_message("<span class='danger'>The [src] jumps back to its user.</span>")
Recall()
/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
..()
if(summoner)
if (get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
src << "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]"
visible_message("<span class='danger'>The [src] jumps back to its user.</span>")
Recall()
/mob/living/simple_animal/hostile/guardian/adjustBruteLoss(amount) //The spirit is invincible, but passes on damage to the summoner
var/damage = amount * damage_transfer
if (summoner)
if(loc == summoner)
return
summoner.adjustBruteLoss(damage)
if(damage)
summoner << "<span class='danger'><B>Your [name] is under attack! You take damage!</span></B>"
summoner.visible_message("<span class='danger'><B>Blood sprays from [summoner] as [src] takes damage!</B></span>")
if(summoner.stat == UNCONSCIOUS)
summoner << "<span class='danger'><B>Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!</span></B>"
summoner.adjustCloneLoss(damage/2)
/mob/living/simple_animal/hostile/guardian/ex_act(severity, target)
switch (severity)
if (1)
gib()
return
if (2)
adjustBruteLoss(60)
if(3)
adjustBruteLoss(30)
/mob/living/simple_animal/hostile/guardian/gib()
if(summoner)
summoner << "<span class='danger'><B>Your [src] was blown up!</span></B>"
summoner.gib()
ghostize()
qdel(src)
/mob/living/simple_animal/hostile/guardian/start_pulling(var/atom/movable/AM)
return //no pulling things fo you!
//Manifest, Recall, Communicate
/mob/living/simple_animal/hostile/guardian/proc/Manifest()
if(cooldown > world.time)
return
if(loc == summoner)
loc = get_turf(summoner)
src.client.eye = loc
cooldown = world.time + 30
if(animated_manifest)
var/end_icon = icon_state
icon_state = "parasite_forming"
spawn(6)
icon_state = end_icon
/mob/living/simple_animal/hostile/guardian/proc/Recall()
if(cooldown > world.time)
return
loc = summoner
buckled = null
cooldown = world.time + 30
/mob/living/simple_animal/hostile/guardian/proc/Communicate()
var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "")
if(!input) return
for(var/mob/M in mob_list)
if(M == summoner || (M in dead_mob_list))
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
log_say("[src.real_name]/[src.key] : [input]")
/mob/living/simple_animal/hostile/guardian/proc/ToggleMode()
src << "<span class='danger'><B>You dont have another mode!</span></B>"
/mob/living/proc/guardian_comm()
set name = "Communicate"
set category = "Guardian"
set desc = "Communicate telepathically with your guardian."
var/input = stripped_input(src, "Please enter a message to tell your guardian.", "Message", "")
if(!input) return
for(var/mob/M in mob_list)
if(istype (M, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/G = M
if(G.summoner == src)
G << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
else if (M in dead_mob_list)
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
log_say("[src.real_name]/[src.key] : [text]")
/mob/living/proc/guardian_recall()
set name = "Recall Guardian"
set category = "Guardian"
set desc = "Forcibly recall your guardian."
for(var/mob/living/simple_animal/hostile/guardian/G in mob_list)
if(G.summoner == src)
G.Recall()
/mob/living/proc/guardian_reset()
set name = "Reset Guardian Player (One Use)"
set category = "Guardian"
set desc = "Re-rolls which ghost will control your Guardian. One use."
for(var/mob/living/simple_animal/hostile/guardian/G in mob_list)
if(G.summoner == src)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [G.real_name]?", "pAI", null, FALSE, 100)
var/mob/dead/observer/new_stand = null
if(candidates.len)
new_stand = pick(candidates)
G << "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance."
src << "Your guardian has been successfully reset."
message_admins("[key_name_admin(new_stand)] has taken control of ([key_name_admin(G)])")
G.ghostize()
G.key = new_stand.key
src.verbs -= /mob/living/proc/guardian_reset
else
src << "There were no ghosts willing to take control. Looks like you're stuck with your Guardian for now."
/mob/living/simple_animal/hostile/guardian/proc/ToggleLight()
if(!luminosity)
set_light(3)
else
set_light(0)
//////////////////////////TYPES OF GUARDIANS
//Fire. Low damage, low resistance, sets mobs on fire when bumping
/mob/living/simple_animal/hostile/guardian/fire
a_intent = I_HELP
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/Welder.ogg'
attacktext = "sears"
damage_transfer = 0.8
range = 10
playstyle_string = "As a Chaos type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will randomly teleport enemies."
environment_smash = 1
magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!"
tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random."
/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies
..()
if(summoner)
summoner.ExtinguishMob()
summoner.adjust_fire_stacks(-20)
/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
..()
if(prob(45))
if(istype(target, /atom/movable))
var/atom/movable/M = target
if(!M.anchored && M != summoner)
do_teleport(M, M, 10)
/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
..()
collision_ignite(AM)
/mob/living/simple_animal/hostile/guardian/fire/Bumped(AM as mob|obj)
..()
collision_ignite(AM)
/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
..()
collision_ignite(AM)
/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
if(istype(AM, /mob/living/))
var/mob/living/M = AM
if(AM != summoner && M.fire_stacks < 7)
M.fire_stacks = 7
M.IgniteMob()
/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
..()
collision_ignite(AM)
//Standard
/mob/living/simple_animal/hostile/guardian/punch
melee_damage_lower = 20
melee_damage_upper = 20
damage_transfer = 0.5
playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
environment_smash = 2
magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated."
tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm stirs to life, ready to tear apart your enemies."
var/battlecry = "AT"
/mob/living/simple_animal/hostile/guardian/punch/sealpunch
melee_damage_lower = 0
melee_damage_upper = 0
melee_damage_type = STAMINA
damage_transfer = 0.2
playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
environment_smash = 2
battlecry = "URK"
/mob/living/simple_animal/hostile/guardian/punch/verb/Battlecry()
set name = "Set Battlecry"
set category = "Guardian"
set desc = "Choose what you shout as you punch"
var/input = stripped_input(src,"What do you want your battlecry to be? Max length of 5 characters.", ,"", 6)
if(input)
battlecry = input
/mob/living/simple_animal/hostile/guardian/punch/AttackingTarget()
..()
if(iscarbon(target) && target != summoner)
if(length(battlecry) > 11)//no more then 11 letters in a battle cry.
src.visible_message("<span class='danger'><B>[src] punches [target]!</B></span>")
else
src.say("[src.battlecry][src.battlecry][src.battlecry][src.battlecry][src.battlecry]")
playsound(loc, src.attack_sound, 50, 1, 1)
playsound(loc, src.attack_sound, 50, 1, 1)
playsound(loc, src.attack_sound, 50, 1, 1)
playsound(loc, src.attack_sound, 50, 1, 1)
//Healer
/mob/living/simple_animal/hostile/guardian/healer
a_intent = I_HARM
friendly = "heals"
speed = 0
melee_damage_lower = 15
melee_damage_upper = 15
playstyle_string = "As a Support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent mob will warp them to your bluespace beacon after a short delay."
magic_fluff_string = "..And draw the CMO, a potent force of life...and death."
tech_fluff_string = "Boot sequence complete. Medical modules active. Bluespace modules activated. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace."
var/turf/simulated/floor/beacon
var/beacon_cooldown = 0
var/toggle = FALSE
/mob/living/simple_animal/hostile/guardian/healer/sealhealer
a_intent = I_HARM
friendly = "heals"
speed = 0
melee_damage_lower = 0
melee_damage_upper = 0
melee_damage_type = STAMINA
/mob/living/simple_animal/hostile/guardian/healer/New()
..()
/mob/living/simple_animal/hostile/guardian/healer/Life()
..()
regular_hud_updates()
process_med_hud(src, 1)
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
..()
if(toggle == TRUE)
if(src.loc == summoner)
src << "<span class='danger'><B>You must be manifested to heal!</span></B>"
return
if(iscarbon(target))
var/mob/living/carbon/C = target
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
C.adjustOxyLoss(-5)
C.adjustToxLoss(-5)
/mob/living/simple_animal/hostile/guardian/healer/ToggleMode()
if(src.loc == summoner)
if(toggle)
a_intent = I_HARM
speed = 0
damage_transfer = 0.7
melee_damage_lower = 15
melee_damage_upper = 15
src << "<span class='danger'><B>You switch to combat mode.</span></B>"
toggle = FALSE
else
a_intent = I_HELP
speed = 1
damage_transfer = 1
melee_damage_lower = 0
melee_damage_upper = 0
src << "<span class='danger'><B>You switch to healing mode.</span></B>"
toggle = TRUE
else
src << "<span class='danger'><B>You have to be recalled to toggle modes!</span></B>"
/mob/living/simple_animal/hostile/guardian/healer/verb/Beacon()
set name = "Place Bluespsace Beacon"
set category = "Guardian"
set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions."
if(beacon_cooldown<world.time)
var/turf/beacon_loc = get_turf(src.loc)
if(istype(beacon_loc, /turf/simulated/floor))
var/turf/simulated/floor/F = beacon_loc
F.icon = 'icons/turf/floors.dmi'
F.name = "bluespace recieving pad"
F.desc = "A recieving zone for bluespace teleportations. Building a wall over it should disable it."
F.icon_state = "light_on-w"
src << "<span class='danger'><B>Beacon placed! You may now warp targets to it, including your user, via Alt+Click. </span></B>"
if(beacon)
beacon.ChangeTurf(/turf/simulated/floor/plating)
beacon = F
beacon_cooldown = world.time+3000
else
src << "<span class='danger'><B>Your power is on cooldown. You must wait five minutes between placing beacons.</span></B>"
/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
if(!istype(A))
return
if(src.loc == summoner)
src << "<span class='danger'><B>You must be manifested to warp a target!</span></B>"
return
if(!beacon)
src << "<span class='danger'><B>You need a beacon placed to warp things!</span></B>"
return
if(!Adjacent(A))
src << "<span class='danger'><B>You must be adjacent to your target!</span></B>"
return
if((A.anchored))
src << "<span class='danger'><B>Your target can not be anchored!</span></B>"
return
src << "<span class='danger'><B>You begin to warp [A]</span></B>"
if(do_mob(src, A, 50))
if(!A.anchored)
if(src.beacon) //Check that the beacon still exists and is in a safe place. No instant kills.
if(beacon.air)
var/datum/gas_mixture/Z = beacon.air
if(Z.oxygen >= 16 && !Z.toxins && Z.carbon_dioxide < 10 && !Z.trace_gases.len)
if((Z.temperature > 270) && (Z.temperature < 360))
var/pressure = Z.return_pressure()
if((pressure > 20) && (pressure < 550))
do_teleport(A, beacon, 0)
else
src << "<span class='danger'><B>The beacon isn't in a safe location!</span></B>"
else
src << "<span class='danger'><B>The beacon isn't in a safe location!</span></B>"
else
src << "<span class='danger'><B>You need a beacon to warp things!</span></B>"
else
src << "<span class='danger'><B>You need to hold still!</span></B>"
///////////////////Ranged
/obj/item/projectile/guardian
name = "crystal spray"
icon_state = "guardian"
damage = 5
damage_type = BRUTE
armour_penetration = 100
/mob/living/simple_animal/hostile/guardian/ranged
a_intent = I_HELP
friendly = "quietly assesses"
melee_damage_lower = 10
melee_damage_upper = 10
damage_transfer = 0.9
projectiletype = /obj/item/projectile/guardian
ranged_cooldown_cap = 0
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
ranged = 1
range = 13
playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit."
magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat."
tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal."
var/list/snares = list()
var/toggle = FALSE
/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode()
if(src.loc == summoner)
if(toggle)
ranged = 1
melee_damage_lower = 10
melee_damage_upper = 10
alpha = 255
range = 13
incorporeal_move = 0
src << "<span class='danger'><B>You switch to combat mode.</span></B>"
toggle = FALSE
else
ranged = 0
melee_damage_lower = 0
melee_damage_upper = 0
alpha = 60
range = 255
incorporeal_move = 1
src << "<span class='danger'><B>You switch to scout mode.</span></B>"
toggle = TRUE
else
src << "<span class='danger'><B>You have to be recalled to toggle modes!</span></B>"
/mob/living/simple_animal/hostile/guardian/ranged/verb/Snare()
set name = "Set Surveillance Trap"
set category = "Guardian"
set desc = "Set an invisible trap that will alert you when living creatures walk over it. Max of 5"
if(src.snares.len <6)
var/turf/snare_loc = get_turf(src.loc)
var/obj/item/effect/snare/S = new /obj/item/effect/snare(snare_loc)
S.spawner = src
S.name = "[get_area(snare_loc)] trap ([rand(1, 1000)])"
src.snares |= S
src << "<span class='danger'><B>Surveillance trap deployed!</span></B>"
else
src << "<span class='danger'><B>You have too many traps deployed. Delete some first.</span></B>"
/mob/living/simple_animal/hostile/guardian/ranged/verb/DisarmSnare()
set name = "Remove Surveillance Trap"
set category = "Guardian"
set desc = "Disarm unwanted surveillance traps."
var/picked_snare = input(src, "Pick which trap to disarm", "Disarm Trap") as null|anything in src.snares
if(picked_snare)
src.snares -= picked_snare
qdel(picked_snare)
src << "<span class='danger'><B>Snare disarmed.</span></B>"
/obj/item/effect/snare
name = "snare"
desc = "You shouldn't be seeing this!"
var/mob/living/spawner
invisibility = 1
/obj/item/effect/snare/Crossed(AM as mob|obj)
if(istype(AM, /mob/living/))
var/turf/snare_loc = get_turf(src.loc)
if(spawner)
spawner << "<span class='danger'><B>[AM] has crossed your surveillance trap at [get_area(snare_loc)].</span></B>"
if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/G = spawner
if(G.summoner)
G.summoner << "<span class='danger'><B>[AM] has crossed your surveillance trap at [get_area(snare_loc)].</span></B>"
////Bomb
/mob/living/simple_animal/hostile/guardian/bomb
melee_damage_lower = 15
melee_damage_upper = 15
damage_transfer = 0.6
range = 13
playstyle_string = "As an explosive type, you have only moderate close combat abilities, but are capable of converting any adjacent item into a disguised bomb via alt click."
magic_fluff_string = "..And draw the Scientist, master of explosive death."
tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items."
var/bomb_cooldown = 0
/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
if(!istype(A))
return
if(src.loc == summoner)
src << "<span class='danger'><B>You must be manifested to create bombs!</span></B>"
return
if(istype(A, /obj/))
if(bomb_cooldown <= world.time && !stat)
var/obj/item/weapon/guardian_bomb/B = new /obj/item/weapon/guardian_bomb(get_turf(A))
src << "<span class='danger'><B>Success! Bomb armed!</span></B>"
bomb_cooldown = world.time + 200
B.spawner = src
B.disguise (A)
else
src << "<span class='danger'><B>Your powers are on cooldown! You must wait 20 seconds between bombs.</span></B>"
/obj/item/weapon/guardian_bomb
name = "bomb"
desc = "You shouldn't be seeing this!"
var/obj/stored_obj
var/mob/living/spawner
/obj/item/weapon/guardian_bomb/proc/disguise(var/obj/A)
A.loc = src
stored_obj = A
anchored = A.anchored
density = A.density
appearance = A.appearance
spawn(600)
stored_obj.loc = get_turf(src.loc)
spawner << "<span class='danger'><B>Failure! Your trap didn't catch anyone this time.</span></B>"
qdel(src)
/obj/item/weapon/guardian_bomb/proc/detonate(var/mob/living/user)
user << "<span class='danger'><B>The [src] was boobytrapped!</span></B>"
spawner << "<span class='danger'><B>Success! Your trap caught [user]</span></B>"
stored_obj.loc = get_turf(src.loc)
playsound(get_turf(src),'sound/effects/Explosion2.ogg', 200, 1)
user.ex_act(2)
qdel(src)
/obj/item/weapon/guardian_bomb/attackby(mob/living/user)
detonate(user)
return
/obj/item/weapon/guardian_bomb/pickup(mob/living/user)
detonate(user)
return
/obj/item/weapon/guardian_bomb/examine(mob/user)
stored_obj.examine(user)
if(get_dist(user,src)<=2)
user << "<span class='notice'>Looks odd!</span>"
////////Creation
/obj/item/weapon/guardiancreator
name = "deck of tarot cards"
desc = "An enchanted deck of tarot cards, rumored to be a source of unimaginable power. "
icon = 'icons/obj/toy.dmi'
icon_state = "deck_syndicate_full"
var/used = FALSE
var/theme = "magic"
var/mob_name = "Guardian Spirit"
var/use_message = "You shuffle the deck..."
var/used_message = "All the cards seem to be blank now."
var/failure_message = "..And draw a card! It's...blank? Maybe you should try again later."
var/ling_failure = "The deck refuses to respond to a souless creature such as you."
var/list/possible_guardians = list("Chaos", "Standard", "Ranged", "Support", "Explosive")
var/random = TRUE
var/adminseal = FALSE
/obj/item/weapon/guardiancreator/attack_self(mob/living/user)
for(var/mob/living/simple_animal/hostile/guardian/G in living_mob_list)
if (G.summoner == user)
user << "You already have a [mob_name]!"
return
if(user.mind && user.mind.changeling)
user << "[ling_failure]"
return
if(used == TRUE)
user << "[used_message]"
return
used = TRUE
user << "[use_message]"
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?",BE_PAI, null, FALSE, 100)
var/mob/dead/observer/theghost = null
if(candidates.len)
theghost = pick(candidates)
spawn_guardian(user, theghost.key)
else
user << "[failure_message]"
used = FALSE
/obj/item/weapon/guardiancreator/proc/spawn_guardian(var/mob/living/user, var/key)
var/gaurdiantype = "Standard"
if(random)
gaurdiantype = pick(possible_guardians)
if(adminseal)
gaurdiantype = pick("StandardSeal","SupportSeal")
else
gaurdiantype = input(user, "Pick the type of [mob_name]", "[mob_name] Creation") as null|anything in possible_guardians
var/pickedtype = /mob/living/simple_animal/hostile/guardian/punch
var/picked_color = pick("#FFFFFF","#000000","#808080","#A52A2A","#FF0000","#8B0000","#DC143C","#FFA500","#FFFF00","#008000","#00FF00","#006400","#00FFFF","#0000FF","#000080","#008080","#800080","#4B0082")
switch(gaurdiantype)
if("Chaos")
pickedtype = /mob/living/simple_animal/hostile/guardian/fire
if("Standard")
pickedtype = /mob/living/simple_animal/hostile/guardian/punch
if("StandardSeal")
pickedtype = /mob/living/simple_animal/hostile/guardian/punch/sealpunch
if("Ranged")
pickedtype = /mob/living/simple_animal/hostile/guardian/ranged
if("Support")
pickedtype = /mob/living/simple_animal/hostile/guardian/healer
if("SupportSeal")
pickedtype = /mob/living/simple_animal/hostile/guardian/healer/sealhealer
if("Explosive")
pickedtype = /mob/living/simple_animal/hostile/guardian/bomb
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user)
G.summoner = user
G.key = key
G << "You are a [mob_name] bound to serve [user.real_name]."
G << "You are capable of manifesting or recalling to your master with verbs in the Guardian tab. You will also find a verb to communicate with them privately there."
G << "While personally invincible, you will die if [user.real_name] does, and any damage dealt to you will have a portion passed on to them as you feed upon them to sustain yourself."
G << "[G.playstyle_string]"
user.verbs += /mob/living/proc/guardian_comm
if(!adminseal)
user.verbs += /mob/living/proc/guardian_recall
user.verbs += /mob/living/proc/guardian_reset
switch (theme)
if("magic")
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
user << "[G.magic_fluff_string]."
if("tech")
var/colour = pick("orange", "neon", "pink", "red", "blue", "green")
G.name = "[mob_name] [capitalize(colour)]"
G.real_name = "[mob_name] [capitalize(colour)]"
G.icon_living = "parasite[colour]"
G.icon_state = "parasite[colour]"
G.animated_manifest = TRUE
user << "[G.tech_fluff_string]."
G.speak_emote = list("states")
if("bio")
user << "[G.bio_fluff_string]."
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
G.icon_living = "headcrab"
G.icon_state = "headcrab"
G.attacktext = "swarms"
G.speak_emote = list("chitters")
if("seal")
user << "[G.admin_fluff_string]."
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
G.icon = 'icons/mob/animal.dmi'
G.icon_living = "seal"
G.icon_state = "seal"
G.attacktext = "slaps"
G.speak_emote = list("barks")
/obj/item/weapon/guardiancreator/choose
random = FALSE
/obj/item/weapon/guardiancreator/tech
name = "holoparasite injector"
desc = "It contains alien nanoswarm of unknown origin. Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, it requires an organic host as a home base and source of fuel."
icon = 'icons/obj/syringe.dmi'
icon_state = "combat_hypo"
theme = "tech"
mob_name = "Holoparasite"
use_message = "You start to power on the injector..."
used_message = "The injector has already been used."
failure_message = "<B>...ERROR. BOOT SEQUENCE ABORTED. AI FAILED TO INTIALIZE. PLEASE CONTACT SUPPORT OR TRY AGAIN LATER.</B>"
ling_failure = "The holoparasites recoil in horror. They want nothing to do with a creature like you."
/obj/item/weapon/guardiancreator/tech/choose
random = FALSE
/obj/item/weapon/guardiancreator/biological
name = "scarab egg cluster"
desc = "A parasitic species that will nest in the closest living creature upon birth. While not great for your health, they'll defend their new 'hive' to the death."
icon = 'icons/obj/fish_items.dmi'
icon_state = "eggs"
theme = "bio"
mob_name = "Scarab Swarm"
use_message = "The eggs begin to twitch..."
used_message = "The cluster already hatched."
failure_message = "<B>...but soon settles again. Guess they weren't ready to hatch after all.</B>"
/obj/item/weapon/guardiancreator/biological/choose
random = FALSE
/obj/item/weapon/guardiancreator/adminbus
name = "Avatar deck"
desc = "A mystical deck..oddly all the cards have a form of Bus on them."
icon = 'icons/obj/toy.dmi'
icon_state = "deck_syndicate_full"
theme = "seal"
mob_name = "Avatar"
use_message = "URK!"
used_message = "arf?"
failure_message = "<B>...</B>"
adminseal = TRUE
/obj/item/weapon/guardiancreator/adminbus/attack_self(mob/living/user)
var/list/targets = list()
var/target = null
targets += getmobs() //Fill list, prompt user with list
target = input("Select a Player to guard!", "Player list", null, null) as null|anything in targets
if(!target) return
var/mob/living/carbon/human/H = target
if(H.mind )
spawn_guardian(H,user.key)
else
user << "Target has no mind. Aborting."
/obj/item/weapon/paper/guardian
name = "Holoparasite Guide"
icon_state = "paper"
info = {"<b>A list of Holoparasite Types</b><br>
<br>
<b>Chaos</b>: Ignites mobs on touch. teleports them at random on attack. Automatically extinguishes the user if they catch fire.<br>
<br>
<b>Standard</b>:Devestating close combat attacks and high damage resist. No special powers.<br>
<br>
<b>Ranged</b>: Has two modes. Ranged: Extremely weak, highly spammable projectile attack. Scout: Can not attack, but can move through walls. Can lay surveillance snares in either mode.<br>
<br>
<b>Support</b>:Has two modes. Combat: Medium power attacks and damage resist. Healer: Attacks heal damage, but low damage resist and slow movemen. Can deploy a bluespace beacon and warp targets to it (including you) in either mode.<br>
<br>
<b>Explosive</b>: High damage resist and medium power attack. Can turn any object into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered.<br>
"}
/obj/item/weapon/paper/guardian/update_icon()
return
/obj/item/weapon/storage/box/syndie_kit/guardian
name = "holoparasite injector kit"
/obj/item/weapon/storage/box/syndie_kit/guardian/New()
..()
new /obj/item/weapon/guardiancreator/tech/choose(src)
new /obj/item/weapon/paper/guardian(src)
return
///HUD
/datum/hud/proc/guardian_hud(ui_style = 'icons/mob/screen1_midnight.dmi')
adding = list()
var/obj/screen/using
using = new /obj/screen/guardian/Manifest()
using.screen_loc = ui_rhand
adding += using
using = new /obj/screen/guardian/Recall()
using.screen_loc = ui_lhand
adding += using
using = new /obj/screen/guardian/ToggleMode()
using.screen_loc = ui_storage1
adding += using
using = new /obj/screen/guardian/ToggleLight()
using.screen_loc = ui_inventory
adding += using
using = new /obj/screen/guardian/Communicate()
using.screen_loc = ui_back
adding += using
mymob.client.screen = list()
mymob.client.screen += mymob.client.void
mymob.client.screen += adding
//HUD BUTTONS
/obj/screen/guardian
icon = 'icons/mob/guardian.dmi'
/obj/screen/guardian/Manifest
icon_state = "manifest"
name = "Manifest"
desc = "Spring forth into battle!"
/obj/screen/guardian/Manifest/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Manifest()
/obj/screen/guardian/Recall
icon_state = "recall"
name = "Recall"
desc = "Return to your user."
/obj/screen/guardian/Recall/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Recall()
/obj/screen/guardian/ToggleMode
icon_state = "toggle"
name = "Toggle Mode"
desc = "Switch between ability modes."
/obj/screen/guardian/ToggleMode/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleMode()
/obj/screen/guardian/Communicate
icon_state = "communicate"
name = "Communicate"
desc = "Communicate telepathically with your user."
/obj/screen/guardian/Communicate/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Communicate()
/obj/screen/guardian/ToggleLight
icon_state = "light"
name = "Toggle Light"
desc = "Glow like star dust."
/obj/screen/guardian/ToggleLight/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleLight()
@@ -256,6 +256,8 @@
E = locate() in get_turf(src)
if(!E)
var/obj/effect/spider/eggcluster/C = new /obj/effect/spider/eggcluster(src.loc)
C.faction = faction
C.master_commander = master_commander
if(ckey)
C.player_spiders = 1
fed--
@@ -52,7 +52,7 @@
..()
visible_message("<b>[src]</b> blows apart!")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
ghostize()
@@ -81,7 +81,7 @@
New()
..()
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(5, 0, src.loc)
smoke.start()
visible_message("\red <B>The [src] warps in!</B>")
@@ -94,11 +94,14 @@
bot_amt--
switch(bot_type)
if("norm")
new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
H.faction = faction
if("range")
new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
R.faction = faction
if("rapid")
new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
F.faction = faction
spawn(100)
qdel(src)
return
@@ -22,7 +22,7 @@
speed = 8
projectiletype = /obj/item/projectile/beam/drone
projectilesound = 'sound/weapons/laser3.ogg'
var/datum/effect/effect/system/ion_trail_follow/ion_trail
var/datum/effect/system/ion_trail_follow/ion_trail
//the drone randomly switches between these states because it's malfunctioning
var/hostile_drone = 0
@@ -85,14 +85,14 @@
//repair a bit of damage
if(prob(1))
src.visible_message("\red \icon[src] [src] shudders and shakes as some of it's damaged systems come back online.")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
health += rand(25,100)
//spark for no reason
if(prob(5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -134,7 +134,7 @@
src.visible_message("\red \icon[src] [src] begins to spark and shake violenty!")
else
src.visible_message("\red \icon[src] [src] sparks and shakes like it's about to explode!")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -164,7 +164,7 @@
/mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy() //Seriously, what the actual hell.
//some random debris left behind
if(has_loot)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
var/obj/O
@@ -77,12 +77,16 @@
return ..()
/mob/living/simple_animal/hostile/statue/Life()
..()
if(!client && target) // If we have a target and we're AI controlled
if(..())
if(!ckey)
spawn() //for saftey
checkTargets()
. = 1
/mob/living/simple_animal/hostile/statue/proc/checkTargets()
if(target)
var/mob/watching = can_be_seen()
// If they're not our target
if(watching && watching != target)
// This one is closer.
if(get_dist(watching, src) > get_dist(target, src))
LoseTarget()
GiveTarget(watching)
@@ -112,82 +116,71 @@
/mob/living/simple_animal/hostile/statue/proc/can_be_seen(var/turf/destination)
// Check for darkness
var/turf/T = get_turf(loc)
var/light_amount
var/DLlight_amount
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = L.lum_r + L.lum_g + L.lum_b
if(T.dynamic_lighting)
light_amount = T.get_lumcount()
else
light_amount = 5
var/atom/movable/lighting_overlay/DL = locate(/atom/movable/lighting_overlay) in destination
if(DL)
DLlight_amount = DL.lum_r + DL.lum_g + DL.lum_b
light_amount = 5
if(destination && destination.dynamic_lighting)
DLlight_amount = destination.get_lumcount()
else
DLlight_amount = 5
DLlight_amount = 5
if(T && destination)
// Don't check it twice if our destination is the tile we are on or we can't even get to our destination
//Don't check it twice if our destination is the tile we are on or we can't even get to our destination
if(T == destination)
destination = null
else if(light_amount < 0.1 && DLlight_amount < 0.1) // No one can see us in the darkness, right?
return null
// We aren't in darkness, loop for viewers.
//We aren't in darkness, loop for viewers.
var/list/check_list = list(src)
if(destination)
check_list += destination
// This loop will, at most, loop twice.
//This loop will, at most, loop twice.
for(var/atom/check in check_list)
for(var/mob/living/M in viewers(world.view + 1, check) - src)
if(M.client && CanAttack(M))
if(M.blinded || (sdisabilities & BLIND))
if(M.blinded || (M.sdisabilities & BLIND))
return null
//calculates if any mobs are actually facing the statue
var/xdif = M.x - src.x
var/ydif = M.y - src.y
if(abs(xdif) < abs(ydif))
//mob is either above or below src
if(ydif < 0 && M.dir == NORTH)
//mob is below src and looking up
if(abs(xdif) < abs(ydif)) //mob is either above or below src
if(ydif < 0 && M.dir == NORTH) //mob is below src and looking up
return M
else if(ydif > 0 && M.dir == SOUTH)
//mob is above src and looking down
if(ydif > 0 && M.dir == SOUTH) //mob is above src and looking down
return M
else if(abs(xdif) > abs(ydif))
//mob is either left or right of src
if(xdif < 0 && M.dir == EAST)
//mob is to the left of src and looking right
else if(abs(xdif) > abs(ydif)) //mob is either left or right of src
if(xdif < 0 && M.dir == EAST) //mob is to the left of src and looking right
return M
else if(xdif > 0 && M.dir == WEST)
//mob is to the right of src and looking left
if(xdif > 0 && M.dir == WEST) //mob is to the right of src and looking left
return M
else if (xdif == 0 && ydif == 0)
//mob is on the same tile as src
else if(xdif == 0 && ydif == 0) //mob is on the same tile as src
return M
return null
// Cannot talk
//Cannot talk
/mob/living/simple_animal/hostile/statue/say()
return 0
// Turn to dust when gibbed
/mob/living/simple_animal/hostile/statue/death(gibbed)
if(!gibbed) //The looping ends here.
dust()
return
return ..()
/mob/living/simple_animal/hostile/statue/gib(var/animation = 0)
dust(animation)
/mob/living/simple_animal/hostile/statue/death()
living_mob_list -= src
dead_mob_list += src
if(key)
respawnable_list += src
gib()
// Stop attacking clientless mobs
//Stop attacking clientless mobs
/mob/living/simple_animal/hostile/statue/CanAttack(var/atom/the_target)
if(mind && mind.key && !ckey)
@@ -343,7 +343,7 @@
//Search for item to steal
parrot_interest = search_for_item()
if(parrot_interest)
custom_emote(1,"looks in [parrot_interest]'s direction and takes flight")
custom_emote(1,"looks in [parrot_interest]'s direction and takes flight.")
parrot_state = PARROT_SWOOP | PARROT_STEAL
icon_state = "parrot_fly"
return
@@ -731,4 +731,4 @@
/mob/living/simple_animal/parrot/proc/parrot_hear(var/message="")
if(!message || stat)
return
speech_buffer.Add(message)
speech_buffer.Add(message)
@@ -2,17 +2,22 @@
//"Ghosts" that are invisible and move like ghosts, cannot take damage while invsible
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
#define INVISIBILITY_REVENANT 50
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
var/icon_idle = "revenant_idle"
var/icon_reveal = "revenant_revealed"
var/icon_stun = "revenant_stun"
var/icon_drain = "revenant_draining"
incorporeal_move = 3
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
see_invisible = SEE_INVISIBLE_OBSERVER
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
maxHealth = INFINITY
see_invisible = INVISIBILITY_REVENANT
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
@@ -23,34 +28,43 @@
harm_intent_damage = 0
friendly = "touches"
status_flags = 0
see_in_dark = 8
wander = 0
density = 0
flying = 1
anchored = 1
var/essence = 25 //The resource of revenants. Max health is equal to three times this amount
var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
var/essence = 75 //The resource of revenants. Max health is equal to three times this amount
var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
var/essence_regenerating = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
var/essence_regen_amount = 2 //How much essence regenerates
var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
var/essence_regen_amount = 5 //How much essence regenerates
var/essence_accumulated = 0 //How much essence the revenant has stolen
var/revealed = 0 //If the revenant can take damage from normal sources.
var/unreveal_time = 0 //How long the revenant is revealed for, is about 2 seconds times this var.
var/unstun_time = 0 //How long the revenant is stunned for, is about 2 seconds times this var.
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
var/essence_drained = 0 //How much essence the revenant has drained.
var/draining = 0 //If the revenant is draining someone.
var/list/drained_mobs = list() //Cannot harvest the same mob twice
var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has.
var/image/ghostimage = null //Visible to ghost with darkness off
/mob/living/simple_animal/revenant/Life()
..()
if(essence < essence_min)
essence = essence_min
if(revealed && essence <= 0)
death()
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
essence += essence_regen_amount
if(essence > essence_regen_cap)
essence = essence_regen_cap
maxHealth = essence * 3
if(!revealed)
health = maxHealth //Heals to full when not revealed
essence = min(essence_regen_cap, essence+essence_regen_amount)
if(unreveal_time && world.time >= unreveal_time)
unreveal_time = 0
revealed = 0
invisibility = INVISIBILITY_REVENANT
src << "<span class='revenboldnotice'>You are once more concealed.</span>"
if(unstun_time && world.time >= unstun_time)
unstun_time = 0
notransform = 0
src << "<span class='revenboldnotice'>You can move again!</span>"
update_spooky_icon()
/mob/living/simple_animal/revenant/ex_act(severity)
return 1 //Immune to the effects of explosions.
@@ -58,6 +72,19 @@
/mob/living/simple_animal/revenant/blob_act()
return 1 //blah blah blobs aren't in tune with the spirit world, or something.
/mob/living/simple_animal/revenant/singularity_act()
return //don't walk into the singularity expecting to find corpses, okay?
/mob/living/simple_animal/revenant/narsie_act()
return //most humans will now be either bones or harvesters, but we're still un-alive.
/mob/living/simple_animal/revenant/adjustBruteLoss(amount)
if(!revealed)
return
essence = max(0, essence-amount)
if(essence == 0)
src << "<span class='revendanger'>You feel your essence fraying!</span>"
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
if(client.buildmode)
build_click(src, client.buildmode, params, A)
@@ -87,62 +114,78 @@
if(!castcheck(0))
return
if(draining)
src << "<span class='warning'>You are already siphoning the essence of a soul!</span>"
src << "<span class='revenwarning'>You are already siphoning the essence of a soul!</span>"
return
if(target in drained_mobs)
src << "<span class='warning'>[target]'s soul is dead and empty.</span>"
src << "<span class='revenwarning'>[target]'s soul is dead and empty.</span>"
return
if(!target.stat)
src << "<span class='notice'>This being's soul is too strong to harvest.</span>"
src << "<span class='revennotice'>This being's soul is too strong to harvest.</span>"
if(prob(10))
target << "You feel as if you are being watched."
return
draining = 1
essence_drained = 2
src << "<span class='notice'>You search for the soul of [target].</span>"
essence_drained = rand(15, 20)
src << "<span class='revennotice'>You search for the soul of [target].</span>"
if(do_after(src, 10, 3, 0, target = target)) //did they get deleted in that second?
if(target.ckey)
src << "<span class='notice'>Their soul burns with intelligence.</span>"
essence_drained += 2
src << "<span class='revennotice'>Their soul burns with intelligence.</span>"
essence_drained += rand(20, 30)
if(target.stat != DEAD)
src << "<span class='notice'>Their soul blazes with life!</span>"
essence_drained += 2
src << "<span class='revennotice'>Their soul blazes with life!</span>"
essence_drained += rand(40, 50)
else
src << "<span class='notice'>Their soul is weak and faltering.</span>"
src << "<span class='revennotice'>Their soul is weak and faltering.</span>"
if(do_after(src, 20, 6, 0, target = target)) //did they get deleted NOW?
switch(essence_drained)
if(1 to 2)
src << "<span class='info'>[target] will not yield much essence. Still, every bit counts.</span>"
if(3 to 4)
src << "<span class='info'>[target] will yield an average amount of essence.</span>"
if(5 to INFINITY)
src << "<span class='info'>Such a feast! [target] will yield much essence to you.</span>"
if(do_after(src, 30, 9, 0, target = target)) //how about now
if(1 to 30)
src << "<span class='revennotice'>[target] will not yield much essence. Still, every bit counts.</span>"
if(30 to 70)
src << "<span class='revennotice'>[target] will yield an average amount of essence.</span>"
if(70 to 90)
src << "<span class='revenboldnotice'>Such a feast! [target] will yield much essence to you.</span>"
if(90 to INFINITY)
src << "<span class='revenbignotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
if(do_after(src, 20, 6, 0, target = target)) //how about now
if(!target.stat)
src << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
src << "<span class='revenwarning'>They are now powerful enough to fight off your draining.</span>"
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
draining = 0
return //hey, wait a minute...
src << "<span class='danger'>You begin siphoning essence from [target]'s soul.</span>"
src << "<span class='revenminor'>You begin siphoning essence from [target]'s soul.</span>"
if(target.stat != DEAD)
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
icon_state = "revenant_draining"
reveal(65)
stun(65)
reveal(27)
stun(27)
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60)
if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained * 5, 0, target)
src << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
target.visible_message("<span class='warning'>[target] gently slumps back onto the ground.</span>")
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
if(do_after(src, 30, 9, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained, 0, target)
if(essence_drained > 90)
essence_regen_cap += 25
perfectsouls += 1
src << "<span class='revenboldnotice'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
src << "<span class='revennotice'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, getting clo--</span>")
drained_mobs.Add(target)
target.death(0)
icon_state = "revenant_idle"
else
src << "<span class='revenwarning'>[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.</span>"
draining = 0
essence_drained = 0
if(target) //Wait, target is WHERE NOW?
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
return
else
src << "<span class='warning'>You are not close enough to siphon [target]'s soul. The link has been broken.</span>"
src << "<span class='revenwarning'>You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.</span>"
draining = 0
essence_drained = 0
return
draining = 0
essence_drained = 0
return
/mob/living/simple_animal/revenant/say(message)
@@ -151,11 +194,17 @@
/mob/living/simple_animal/revenant/Stat()
..()
if(statpanel("Status"))
stat(null, "Current essence: [essence]E")
stat(null, "Current essence: [essence]/[essence_regen_cap]E")
stat(null, "Stolen essence: [essence_accumulated]E")
stat(null, "Stolen perfect souls: [perfectsouls]")
/mob/living/simple_animal/revenant/New()
..()
ghostimage = image(src.icon,src,src.icon_state)
ghost_darkness_images |= ghostimage
updateallghostimages()
spawn(5)
if(src.mind)
src.mind.wipe_memory()
@@ -164,8 +213,8 @@
src << "<span class='deadsay'><font size=3><b>You are a revenant.</b></font></span>"
src << "<b>Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.</b>"
src << "<b>You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.</b>"
src << "<b>You are invincible and invisible to everyone but other ghosts. Some abilities may change this.</b>"
src << "<b>To function, you are to drain the life essence from humans. This essence is a resource and will power all of your abilities.</b>"
src << "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>"
src << "<b>To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.</b>"
src << "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>"
src << "<b>Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.</b>"
var/datum/objective/revenant/objective = new
@@ -186,17 +235,21 @@
/mob/living/simple_animal/revenant/proc/giveSpells()
if(src.mind)
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_harvest
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
src.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction(null))
return 1
return 0
/mob/living/simple_animal/revenant/death()
..()
src << "<span class='userdanger'><b>NO! No... it's too late, you can feel yourself fading...</b></span>"
if(!revealed) //Revenants cannot die if they aren't revealed
return
ghost_darkness_images -= ghostimage
updateallghostimages()
src << "<span class='revendanger'>NO! No... it's too late, you can feel your essence breaking apart...</span>"
notransform = 1
revealed = 1
invisibility = 0
@@ -206,8 +259,9 @@
for(var/i = alpha, i > 0, i -= 10)
sleep(0.1)
alpha = i
visible_message("<span class='danger'>[src]'s body breaks apart into blue dust.</span>")
new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
visible_message("<span class='danger'>[src]'s body breaks apart into a fine pile of blue dust.</span>")
var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
return
@@ -216,8 +270,8 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[src] violently flinches!</span>", \
"<span class='boldannounce'>As the null rod passes through you, you feel your essence draining away!</span>")
essence -= 25 //hella effective
"<span class='revendanger'>As the null rod passes through you, you feel your essence draining away!</span>")
adjustBruteLoss(25) //hella effective
inhibited = 1
spawn(30)
inhibited = 0
@@ -229,13 +283,13 @@
return
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
src << "<span class='warning'>You cannot use abilities from inside of a wall.</span>"
src << "<span class='revenwarning'>You cannot use abilities from inside of a wall.</span>"
return 0
if(src.inhibited)
src << "<span class='warning'>Your powers have been suppressed by nulling energy!</span>"
src << "<span class='revenwarning'>Your powers have been suppressed by nulling energy!</span>"
return 0
if(!src.change_essence_amount(essence_cost, 1))
src << "<span class='warning'>You lack the essence to use that ability.</span>"
src << "<span class='revenwarning'>You lack the essence to use that ability.</span>"
return 0
return 1
@@ -244,16 +298,14 @@
return
if(essence + essence_amt <= 0)
return
essence += essence_amt
essence = max(0, essence)
essence = max(0, essence+essence_amt)
if(essence_amt > 0)
essence_accumulated += essence_amt
essence_accumulated = max(0, essence_accumulated)
essence_accumulated = max(0, essence_accumulated+essence_amt)
if(!silent)
if(essence_amt > 0)
src << "<span class='notice'>Gained [essence_amt]E from [source].</span>"
src << "<span class='revennotice'>Gained [essence_amt]E from [source].</span>"
else
src << "<span class='danger'>Lost [essence_amt]E from [source].</span>"
src << "<span class='revenminor'>Lost [essence_amt]E from [source].</span>"
return 1
/mob/living/simple_animal/revenant/proc/reveal(time)
@@ -263,11 +315,13 @@
return
revealed = 1
invisibility = 0
src << "<span class='warning'>You have been revealed.</span>"
spawn(time)
revealed = 0
invisibility = INVISIBILITY_OBSERVER
src << "<span class='notice'>You are once more concealed.</span>"
if(!unreveal_time)
src << "<span class='revendanger'>You have been revealed!</span>"
unreveal_time = world.time + time
else
src << "<span class='revenwarning'>You have been revealed!</span>"
unreveal_time = unreveal_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
@@ -275,16 +329,31 @@
if(time <= 0)
return
notransform = 1
src << "<span class='warning'>You cannot move!</span>"
spawn(time)
notransform = 0
src << "<span class='notice'>You can move again!</span>"
if(!unstun_time)
src << "<span class='revendanger'>You cannot move!</span>"
unstun_time = world.time + time
else
src << "<span class='revenwarning'>You cannot move!</span>"
unstun_time = unstun_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/update_spooky_icon()
if(revealed)
if(notransform)
if(draining)
icon_state = icon_drain
else
icon_state = icon_stun
else
icon_state = icon_reveal
else
icon_state = icon_idle
/datum/objective/revenant
var/targetAmount = 100
/datum/objective/revenant/New()
targetAmount = rand(100,200)
targetAmount = rand(200,500)
explanation_text = "Absorb [targetAmount] points of essence from humans."
..()
@@ -321,27 +390,23 @@
icon = 'icons/effects/effects.dmi'
icon_state = "revenantEctoplasm"
w_class = 2
var/reforming = 0
var/reformed = 0
var/reforming = 1
var/inert = 0
var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
reforming = 1
reforming = 0
spawn(600) //1 minutes
if(src && reforming)
return reform()
if(src && !reforming)
else
inert = 1
visible_message("<span class='warning'>[src] settles down and seems lifeless.</span>")
return
/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user)
if(reformed)
user << "<span class='warning'>[src] keeps slipping out of your hands, you can't get a hold on it!</span>"
return
..()
/obj/item/weapon/ectoplasm/revenant/attack_self(mob/user)
if(!reforming)
if(!reforming || inert)
return ..()
user.visible_message("<span class='notice'>[user] scatters [src] in all directions.</span>", \
"<span class='notice'>You scatter [src] across the area. The particles slowly fade away.</span>")
@@ -350,39 +415,58 @@
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
if(inert)
return
visible_message("<span class='notice'>[src] breaks into particles upon impact, which fade away to nothingness.</span>")
qdel(src)
/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
..(user)
if(reforming)
user << "<span class='warning'>It is shifting and distorted. It would be wise to destroy this.</span>"
else if(!reforming)
user << "<span class='notice'>It seems inert.</span>"
if(inert)
user << "<span class='revennotice'>It seems inert.</span>"
else if(reforming)
user << "<span class='revenwarning'>It is shifting and distorted. It would be wise to destroy this.</span>"
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
if(inert || !src)
return
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("<span class='boldannounce'>[src] suddenly rises into the air before fading away.</span>")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
qdel(src)
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
message_admins("No candidates were found for the new revenant. Oh well!")
return 0
var/client/C = pick(candidates)
var/key_of_revenant = C.key
if(client_to_revive)
for(var/mob/M in dead_mob_list)
if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead
R.client = client_to_revive
key_of_revenant = client_to_revive.key
if(!key_of_revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
return 0
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
qdel(R)
message_admins("No candidates were found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/client/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
qdel(R)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
qdel(src)
if(src) //Should never happen, but just in case
inert = 1
return 1
@@ -1,18 +1,4 @@
//Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence.
/obj/effect/proc_holder/spell/targeted/revenant_harvest
name = "Harvest"
desc = "Siphons the lingering spectral essence from a human, empowering yourself."
panel = "Revenant Abilities"
charge_max = 0 //Short cooldown
clothes_req = 0
range = 1
/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/carbon/human/target in targets)
spawn(0)
user.Harvest(target)
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
@@ -21,155 +7,185 @@
clothes_req = 0
range = 7
include_user = 0
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
spawn(0)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
log_say("Revenant Transmit: [key_name(usr)]->[key_name(M)]: [msg]")
usr << "<span class='info'><b>You transmit to [M]: </b>[msg]</span>"
M << "<span class='deadsay'><b>A strange voice resonates in your head... </b></span><i>[msg]</I>"
for(var/mob/dead/observer/G in player_list)
G.show_message("<i>Revenant message from <b>[usr]</b> ([ghost_follow_link(usr, ghost=G)]) to <b>[M]</b> ([ghost_follow_link(M, ghost=G)]): [msg]</i>")
log_say("RevenantTransmit: [key_name(user)]->[key_name(M)] : [msg]")
usr << "<span class='revennotice'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='revennotice'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>"
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
action_background_icon_state = "bg_revenant"
panel = "Revenant Abilities (Locked)"
name = "Report this to a coder"
var/reveal = 80 //How long it reveals the revenant in deciseconds
var/stun = 20 //How long it stuns the revenant in deciseconds
var/locked = 1 //If it's locked and needs to be unlocked before use
var/unlock_amount = 100 //How much essence it costs to unlock
var/cast_amount = 50 //How much essence it costs to use
/obj/effect/proc_holder/spell/aoe_turf/revenant/New()
..()
if(locked)
name = "[initial(name)] ([unlock_amount]E)"
else
name = "[initial(name)] ([cast_amount]E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
return 0
if(charge_counter < charge_max)
return 0
if(locked)
if(user.essence <= unlock_amount)
return 0
if(user.essence <= cast_amount)
return 0
return 1
/obj/effect/proc_holder/spell/aoe_turf/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-unlock_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user << "<span class='revennotice'>You have unlocked [initial(name)]!</span>"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return 0
if(!user.castcheck(-cast_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user.reveal(reveal)
user.stun(stun)
user.update_action_buttons()
return 1
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
/obj/effect/proc_holder/spell/aoe_turf/revenant_light
name = "Overload Light (30E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload
name = "Overload Lights"
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
range = 1
var/reveal = 80
var/stun = 20
var/locked = 1
range = 5
stun = 30
cast_amount = 45
var/shock_range = 2
var/shock_damage = 18
action_icon_state = "overload_lights"
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-30))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Overload Lights!</span>"
name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
range = 6
charge_counter = charge_max
return
if(!user.castcheck(-20))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
return
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
sleep(10)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(4, 1, L)
s.start()
sleep(10)
for(var/mob/living/M in orange(4, L))
if(M == user)
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
return
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(25, "[L.name]")
var/datum/effect/effect/system/spark_spread/z = new /datum/effect/effect/system/spark_spread
z.set_up(4, 1, M)
z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
user.reveal(reveal)
user.stun(stun)
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread/
s.set_up(4, 0, L)
s.start()
new/obj/effect/overlay/temp/revenant(L.loc)
sleep(20)
if(!L.on) //wait, wait, don't shock me
return
flick("[L.base_state]2", L)
for(var/mob/living/carbon/human/M in view(shock_range, L))
if(M == user)
return
M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(shock_damage, "[L.name]")
var/datum/effect/system/spark_spread/z = new /datum/effect/system/spark_spread/
z.set_up(4, 0, M)
z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
name = "Defile (35E)"
desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
range = 1
var/reveal = 100
var/stun = 20
var/locked = 1
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-35))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Defile!</span>"
name = "Defile (20E)"
panel = "Revenant Abilities"
locked = 0
range = 3
charge_counter = charge_max
return
if(!user.castcheck(-20))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40))
T.ChangeTurf(/turf/simulated/wall/cult)
if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40))
T.ChangeTurf(/turf/simulated/floor/engine/cult)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel tired.</span>"
human.adjustStaminaLoss(35)
for(var/obj/structure/window/window in T.contents)
window.hit(rand(50,125))
for(var/obj/machinery/light/light in T.contents)
light.flicker() //spooky
user.reveal(reveal)
user.stun(stun)
//Malfunction: Makes bad stuff happen to robots and machines.
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf
name = "Malfunction (50E)"
desc = "Corrupts and damages nearby machines and mechanical objects."
panel = "Revenant Abilities (Locked)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile
name = "Defile"
desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
charge_max = 150
clothes_req = 0
range = 1
var/reveal = 60
var/stun = 30
var/locked = 1
range = 3
unlock_amount = 75
cast_amount = 40
action_icon_state = "defile"
var/stamdamage= 25
var/toxdamage = 5
var/confusion = 50
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-50))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Malfunction!</span>"
name = "Malfunction (15E)"
panel = "Revenant Abilities"
locked = 0
range = 4
charge_counter = charge_max
return
if(!user.castcheck(-15))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/bot/bot in T.contents)
if(!bot.emagged)
bot.locked = 0
bot.open = 1
bot.Emag(null)
for(var/obj/machinery/mach in T.contents)
if(prob(10))
mach.emag_act(null)
empulse(user.loc, 3, 5)
user.reveal(reveal)
user.stun(stun)
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
new/obj/effect/overlay/temp/revenant(T)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")].</span>"
human.adjustStaminaLoss(stamdamage)
human.adjustToxLoss(toxdamage)
human.confused += confusion
new/obj/effect/overlay/temp/revenant(human.loc)
if(!istype(T, /turf/simulated/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/rust)
if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
for(var/obj/structure/window/window in T.contents)
window.hit(rand(50,90))
if(window && window.is_fulltile())
new/obj/effect/overlay/temp/revenant/cracks(window.loc)
for(var/obj/machinery/light/light in T.contents)
light.flicker(30) //spooky
//Malfunction: Makes bad stuff happen to robots and machines.
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction
name = "Malfunction"
desc = "Corrupts and damages nearby machines and mechanical objects."
charge_max = 200
range = 4
unlock_amount = 150
action_icon_state = "malfunction"
//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you.
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/bot/bot in T.contents)
if(!bot.emagged)
new/obj/effect/overlay/temp/revenant(bot.loc)
bot.locked = 0
bot.open = 1
bot.Emag(null)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>"
new/obj/effect/overlay/temp/revenant(human.loc)
human.emp_act(1)
for(var/obj/thing in T.contents)
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
continue
if(prob(20))
if(prob(50))
new/obj/effect/overlay/temp/revenant(thing.loc)
thing.emag_act(null)
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(1)
for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new/obj/effect/overlay/temp/revenant(S.loc)
S.spark_system.start()
S.emp_act(1)
@@ -72,6 +72,8 @@
var/scan_ready = 1
var/simplespecies //Sorry, no spider+corgi buttbabies.
var/master_commander = null //holding var for determining who own/controls a sentient simple animal (for sentience potions).
/mob/living/simple_animal/New()
..()
+8 -9
View File
@@ -22,15 +22,14 @@
var/amp = null
var/quills = 3
/mob/living/simple_animal/vox/armalis/death()
living_mob_list -= src
dead_mob_list += src
stat = DEAD
visible_message("\red <B>[src] shudders violently and explodes!</B>","\red <B>You feel your body rupture!</B>")
explosion(get_turf(loc), -1, -1, 3, 5)
src.gib()
return
/mob/living/simple_animal/vox/armalis/death(gibbed)
if(!gibbed)
stat = DEAD
visible_message("<span class='danger'>[src] shudders violently and explodes!</B>","\red <B>You feel your body rupture!</span>")
explosion(get_turf(loc), -1, -1, 3, 5)
gib()
return
return ..()
/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(O.force)
+6 -1
View File
@@ -142,7 +142,12 @@ proc/isembryo(A)
return 1
return 0
proc/isobserver(A)
/proc/isguardian(A)
if(istype(A, /mob/living/simple_animal/hostile/guardian))
return 1
return 0
/proc/isobserver(A)
if(istype(A, /mob/dead/observer))
return 1
return 0
@@ -5,9 +5,9 @@ datum/preferences
gender = gender_override
else
gender = pick(MALE, FEMALE)
underwear = random_underwear(gender)
undershirt = random_undershirt(gender)
socks = random_socks(gender)
underwear = random_underwear(gender, species)
undershirt = random_undershirt(gender, species)
socks = random_socks(gender, species)
if(species == "Human")
s_tone = random_skin_tone()
h_style = random_hair_style(gender, species)
@@ -223,7 +223,18 @@ datum/preferences
//Tail
if(current_species && (current_species.bodyflags & HAS_TAIL))
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
var/tail_icon
var/tail_icon_state
if(body_accessory)
var/datum/body_accessory/accessory = body_accessory_by_name[body_accessory]
tail_icon = accessory.icon
tail_icon_state = accessory.icon_state
else
tail_icon = "icons/effects/species.dmi"
tail_icon_state = "[current_species.tail]_s"
var/icon/temp = new /icon("icon" = tail_icon, "icon_state" = tail_icon_state)
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin color
@@ -257,19 +268,19 @@ datum/preferences
if(underwear && current_species.clothing_flags & HAS_UNDERWEAR)
var/datum/sprite_accessory/underwear/U = underwear_list[underwear]
if(U)
underwear_s = new/icon(U.icon, "[U.icon_state]_s", ICON_OVERLAY)
underwear_s = new/icon(U.icon, "uw_[U.icon_state]_s", ICON_OVERLAY)
var/icon/undershirt_s = null
if(undershirt && current_species.clothing_flags & HAS_UNDERSHIRT)
var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt]
if(U2)
undershirt_s = new/icon(U2.icon, "[U2.icon_state]_s", ICON_OVERLAY)
undershirt_s = new/icon(U2.icon, "us_[U2.icon_state]_s", ICON_OVERLAY)
var/icon/socks_s = null
if(socks && current_species.clothing_flags & HAS_SOCKS)
var/datum/sprite_accessory/socks/U3 = socks_list[socks]
if(U3)
socks_s = new/icon(U3.icon, "[U3.icon_state]_s", ICON_OVERLAY)
socks_s = new/icon(U3.icon, "sk_[U3.icon_state]_s", ICON_OVERLAY)
var/icon/clothes_s = null
var/uniform_dmi='icons/mob/uniform.dmi'
@@ -28,11 +28,11 @@
L[D.name] = D
switch(D.gender)
if(MALE) male += D.name
if(FEMALE) female += D.name
if(MALE) male[D.name] = D
if(FEMALE) female[D.name] = D
else
male += D.name
female += D.name
male[D.name] = D
female[D.name] = D
return L
/datum/sprite_accessory
@@ -115,16 +115,17 @@
icon_state = "hair_halfbang_alt"
ponytail1
name = "Ponytail 1"
icon_state = "hair_ponytail"
name = "Ponytail male"
icon_state = "hair_ponytailm"
gender = MALE
ponytail2
name = "Ponytail 2"
icon_state = "hair_pa"
name = "Ponytail female"
icon_state = "hair_ponytailf"
gender = FEMALE
ponytail3
name = "Ponytail 3"
name = "Ponytail alt"
icon_state = "hair_ponytail3"
sideponytail
@@ -132,6 +133,17 @@
icon_state = "hair_stail"
gender = FEMALE
highponytail
name = "High Ponytail"
icon_state = "hair_highponytail"
gender = FEMALE
wisp
name = "Wisp"
icon_state = "hair_wisp"
gender = FEMALE
parted
name = "Parted"
icon_state = "hair_parted"
@@ -316,6 +328,7 @@
name = "Balding Hair"
icon_state = "hair_e"
gender = MALE // turnoff!
//////////////////////////////
//////START VG HAIRSTYLES/////
//////////////////////////////
@@ -1006,7 +1019,7 @@
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
species_allowed = list("Human","Unathi","Vox","Diona","Kidan","Grey","Plasmaman","Skellington")
species_allowed = list("Human","Unathi","Vox","Diona","Vulpkanin","Kidan","Grey","Plasmaman","Skellington")
nude
name = "Nude"
@@ -1079,7 +1092,7 @@
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
species_allowed = list("Human","Unathi","Vox","Diona","Kidan","Grey","Plasmaman","Skellington")
species_allowed = list("Human","Unathi","Vox","Diona","Vulpkanin","Kidan","Grey","Plasmaman","Skellington")
/datum/sprite_accessory/undershirt/nude
name = "Nude"
@@ -1318,6 +1331,7 @@
///////////////////////
/datum/sprite_accessory/socks
icon = 'icons/mob/underwear.dmi'
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/nude
name = "Nude"
@@ -1330,111 +1344,95 @@
name = "Normal White"
icon_state = "white_norm"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_norm
name = "Normal Black"
icon_state = "black_norm"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_short
name = "Short White"
icon_state = "white_short"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_short
name = "Short Black"
icon_state = "black_short"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_knee
name = "Knee-high White"
icon_state = "white_knee"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_knee
name = "Knee-high Black"
icon_state = "black_knee"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/thin_knee
name = "Knee-high Thin"
icon_state = "thin_knee"
gender = FEMALE
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/striped_knee
name = "Knee-high Striped"
icon_state = "striped_knee"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/rainbow_knee
name = "Knee-high Rainbow"
icon_state = "rainbow_knee"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_thigh
name = "Thigh-high White"
icon_state = "white_thigh"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_thigh
name = "Thigh-high Black"
icon_state = "black_thigh"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/thin_thigh
name = "Thigh-high Thin"
icon_state = "thin_thigh"
gender = FEMALE
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/striped_thigh
name = "Thigh-high Striped"
icon_state = "striped_thigh"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/rainbow_thigh
name = "Thigh-high Rainbow"
icon_state = "rainbow_thigh"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/pantyhose
name = "Pantyhose"
icon_state = "pantyhose"
gender = FEMALE
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_fishnet
name = "Black Fishnet"
icon_state = "black_fishnet"
gender = NEUTER
species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/vox_white
name = "Vox White"
+2 -2
View File
@@ -3,7 +3,7 @@
var/obj/access = new()
var/emagged = 0
var/ui_ref
var/list/monitored_alarms = list()
var/list/monitored_alarms = null
/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
..()
@@ -23,7 +23,7 @@
if(href_list["alarm"])
if(ui_ref)
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms ? monitored_alarms : machines)
if(alarm)
var/datum/topic_state/TS = generate_state(alarm)
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
+2 -2
View File
@@ -7,7 +7,7 @@
throwforce = 20
armour_penetration = 15
var/cooldown = 0 // Because spam aint cool, yo.
var/datum/effect/effect/system/spark_spread/spark_system
var/datum/effect/system/spark_spread/spark_system
/obj/item/weapon/katana/energy/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
@@ -69,7 +69,7 @@
/obj/item/weapon/katana/energy/New()
..()
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
+1 -1
View File
@@ -858,7 +858,7 @@ Note that amputating the affected organ does in fact remove the infection from t
"<span class='danger'>Your [src.name] explodes!</span>",\
"<span class='danger'>You hear an explosion!</span>")
explosion(get_turf(owner),-1,-1,2,3)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, victim)
spark_system.attach(owner)
spark_system.start()
+3 -2
View File
@@ -5,14 +5,14 @@
max_damage = 50 //made same as arm, since it is not vital
min_broken_damage = 30
encased = null
/obj/item/organ/external/head/ipc/New()
robotize("Morpheus Cyberkinetics")
..()
/obj/item/organ/external/chest/ipc
encased = null
/obj/item/organ/external/chest/ipc/New()
robotize("Morpheus Cyberkinetics")
..()
@@ -91,6 +91,7 @@
organ_tag = "brain"
parent_organ = "chest"
vital = 1
max_damage = 200
var/obj/item/device/mmi/stored_mmi
/obj/item/organ/mmi_holder/proc/update_from_mmi()
+6 -2
View File
@@ -35,8 +35,12 @@
user << "<span class='notice'>You put the [W] into \the [src].</span>"
update_icon()
else if(istype(W, /obj/item/weapon/pen))
var/n_name = sanitize(copytext(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, 1, MAX_NAME_LEN))
if((loc == usr && usr.stat == 0))
var/n_name = input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text|null
if(!n_name)
return
n_name = sanitize(copytext(n_name, 1, MAX_NAME_LEN))
if((loc == usr || Adjacent(usr)) && usr.stat == 0)
name = "folder[(n_name ? text("- '[n_name]'") : null)]"
return
+107 -1
View File
@@ -13,6 +13,7 @@
var/copies = 1 //how many copies to print!
var/toner = 30 //how much toner is left! woooooo~
var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
var/mob/living/ass = null
/obj/machinery/photocopier/attack_ai(mob/user as mob)
return attack_hand(user)
@@ -21,7 +22,7 @@
user.set_machine(src)
var/dat = "Photocopier<BR><BR>"
if(copyitem)
if(copyitem || (ass && (ass.loc == src.loc)))
dat += "<a href='byond://?src=\ref[src];remove=1'>Remove Item</a><BR>"
if(toner)
dat += "<a href='byond://?src=\ref[src];copy=1'>Copy</a><BR>"
@@ -57,6 +58,9 @@
else if (istype(copyitem, /obj/item/weapon/paper_bundle))
var/obj/item/weapon/paper_bundle/B = bundlecopy(copyitem)
sleep(15*B.amount)
else if (ass && ass.loc == src.loc)
copyass()
sleep(15)
else
usr << "<span class='warning'>\The [copyitem] can't be copied by \the [src].</span>"
break
@@ -70,6 +74,9 @@
usr << "<span class='notice'>You take \the [copyitem] out of \the [src].</span>"
copyitem = null
updateUsrDialog()
else if(check_ass())
ass << "<span class='notice'>You feel a slight pressure on your ass.</span>"
updateUsrDialog()
else if(href_list["min"])
if(copies > 1)
copies--
@@ -127,6 +134,17 @@
playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
anchored = !anchored
user << "<span class='notice'>You [anchored ? "wrench" : "unwrench"] \the [src].</span>"
else if(istype(O, /obj/item/weapon/grab)) //For ass-copying.
var/obj/item/weapon/grab/G = O
if(ismob(G.affecting) && G.affecting != ass)
var/mob/GM = G.affecting
visible_message("<span class='warning'>[usr] drags [GM.name] onto the photocopier!</span>")
GM.loc = get_turf(src)
ass = GM
if(copyitem)
copyitem.loc = src.loc
copyitem = null
updateUsrDialog()
return
/obj/machinery/photocopier/ex_act(severity)
@@ -203,6 +221,64 @@
visible_message("<span class='notice'>A red light on \the [src] flashes, indicating that it is out of toner.</span>")
return p
/obj/machinery/photocopier/proc/copyass()
var/icon/temp_img
if(check_ass()) //You have to be sitting on the copier and either be a xeno or a human without clothes on.
if(ishuman(ass)) //Suit checks are in check_ass
var/mob/living/carbon/human/H = ass
switch(H.get_species())
if("Human")
temp_img = icon('icons/obj/butts.dmi', "human")
if("Tajaran")
temp_img = icon('icons/obj/butts.dmi', "tajaran")
if("Unathi")
temp_img = icon('icons/obj/butts.dmi', "unathi")
if("Skrell")
temp_img = icon('icons/obj/butts.dmi', "skrell")
if("Vox")
temp_img = icon('icons/obj/butts.dmi', "vox")
if("Kidan")
temp_img = icon('icons/obj/butts.dmi', "kidan")
if("Grey")
temp_img = icon('icons/obj/butts.dmi', "grey")
if("Diona")
temp_img = icon('icons/obj/butts.dmi', "diona")
if("Slime People")
temp_img = icon('icons/obj/butts.dmi', "slime")
if("Vulpkanin")
temp_img = icon('icons/obj/butts.dmi', "vulp")
if("Machine")
temp_img = icon('icons/obj/butts.dmi', "machine")
if("Plasmaman")
temp_img = icon('icons/obj/butts.dmi', "plasma")
else
temp_img = icon('icons/obj/butts.dmi', "human")
else if(istype(ass,/mob/living/silicon/robot/drone))
temp_img = icon('icons/obj/butts.dmi', "drone")
else if(istype(ass,/mob/living/simple_animal/diona))
temp_img = icon('icons/obj/butts.dmi', "nymph")
else if(isalien(ass) || istype(ass,/mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro.
temp_img = icon('icons/obj/butts.dmi', "xeno")
else return
else
return
var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (loc)
p.desc = "You see [ass]'s ass on the photo."
p.pixel_x = rand(-10, 10)
p.pixel_y = rand(-10, 10)
p.img = temp_img
var/icon/small_img = icon(temp_img) //Icon() is needed or else temp_img will be rescaled too >.>
var/icon/ic = icon('icons/obj/items.dmi',"photo")
small_img.Scale(8, 8)
ic.Blend(small_img,ICON_OVERLAY, 10, 13)
p.icon = ic
toner -= 5
if(toner < 0)
toner = 0
visible_message("<span class='notice'>A red light on \the [src] flashes, indicating that it is out of toner.</span>")
return p
//If need_toner is 0, the copies will still be lightened when low on toner, however it will not be prevented from printing. TODO: Implement print queues for fax machines and get rid of need_toner
/obj/machinery/photocopier/proc/bundlecopy(var/obj/item/weapon/paper_bundle/bundle, var/need_toner=1)
var/obj/item/weapon/paper_bundle/p = new /obj/item/weapon/paper_bundle (src)
@@ -227,6 +303,36 @@
p.pixel_x = rand(-9, 9)
return p
/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/user)
check_ass() //Just to make sure that you can re-drag somebody onto it after they moved off.
if (!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai) || target == ass)
return
src.add_fingerprint(user)
if(target == user && !user.incapacitated())
visible_message("<span class='warning'>[usr] jumps onto the photocopier!</span>")
else if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
if(target.anchored) return
if(!ishuman(user)) return
visible_message("<span class='warning'>[usr] drags [target.name] onto the photocopier!</span>")
target.loc = get_turf(src)
ass = target
if(copyitem)
copyitem.loc = src.loc
visible_message("<span class='notice'>[copyitem] is shoved out of the way by [ass]!</span>")
copyitem = null
updateUsrDialog()
/obj/machinery/photocopier/proc/check_ass() //I'm not sure wether I made this proc because it's good form or because of the name.
if(!ass)
return 0
if(ass.loc != src.loc)
ass = null
updateUsrDialog()
return 0
else
return 1
/obj/item/device/toner
name = "toner cartridge"
icon_state = "tonercartridge"
+76 -17
View File
@@ -150,6 +150,24 @@
var/icon_on = "camera"
var/icon_off = "camera_off"
var/size = 3
var/see_ghosts = 0 //for the spoop of it
/obj/item/device/camera/spooky/CheckParts()
var/obj/item/device/camera/C = locate(/obj/item/device/camera) in contents
if(C)
pictures_max = C.pictures_max
pictures_left = C.pictures_left
visible_message("[C] has been imbued with godlike power!")
qdel(C)
var/list/SpookyGhosts = list("ghost","shade","shade2","ghost-narsie","horror","shadow","ghostian2")
/obj/item/device/camera/spooky
name = "camera obscura"
desc = "A polaroid camera, some say it can see ghosts!"
see_ghosts = 1
/obj/item/device/camera/verb/change_size()
set name = "Set Photo Focus"
@@ -184,7 +202,7 @@
..()
/obj/item/device/camera/proc/get_icon(list/turfs, turf/center)
/obj/item/device/camera/proc/get_icon(list/turfs, turf/center,mob/user)
//Bigger icon base to capture those icons that were shifted to the next tile
//i.e. pretty much all wall-mounted machinery
@@ -199,8 +217,20 @@
atoms.Add(the_turf);
// As well as anything that isn't invisible.
for(var/atom/A in the_turf)
if(A.invisibility) continue
atoms.Add(A)
if(A.invisibility )
if(see_ghosts && istype(A,/mob/dead/observer))
var/mob/dead/observer/O = A
if(O.following)
continue
if(user.mind && !(user.mind.assigned_role == "Chaplain"))
atoms.Add(image('icons/mob/mob.dmi', O.loc, pick(SpookyGhosts), 4, SOUTH))
else
atoms.Add(image('icons/mob/mob.dmi', O.loc, "ghost", 4, SOUTH))
else//its not a ghost
continue
else//not invisable, not a spookyghost add it.
atoms.Add(A)
// Sort the atoms into their layers
var/list/sorted = sort_atoms_by_layer(atoms)
@@ -235,21 +265,35 @@
/obj/item/device/camera/proc/get_mobs(turf/the_turf as turf)
var/mob_detail
for(var/mob/living/carbon/A in the_turf)
if(A.invisibility) continue
var/holding = null
if(A.l_hand || A.r_hand)
if(A.l_hand) holding = "They are holding \a [A.l_hand]"
if(A.r_hand)
if(holding)
holding += " and \a [A.r_hand]"
for(var/mob/M in the_turf)
if(M.invisibility)
if(see_ghosts && istype(M,/mob/dead/observer))
var/mob/dead/observer/O = M
if(O.following)
continue
if(!mob_detail)
mob_detail = "You can see a g-g-g-g-ghooooost! "
else
holding = "They are holding \a [A.r_hand]"
mob_detail += "You can also see a g-g-g-g-ghooooost!"
else
continue
if(!mob_detail)
mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
else
mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
var/holding = null
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/A = M
if(A.l_hand || A.r_hand)
if(A.l_hand) holding = "They are holding \a [A.l_hand]"
if(A.r_hand)
if(holding)
holding += " and \a [A.r_hand]"
else
holding = "They are holding \a [A.r_hand]"
if(!mob_detail)
mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
else
mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
return mob_detail
/obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
@@ -263,6 +307,9 @@
user << "<span class='notice'>[pictures_left] photos left.</span>"
icon_state = icon_off
on = 0
if(user.mind && !(user.mind.assigned_role == "Chaplain"))
if(prob(24))
handle_haunt(user)
spawn(64)
icon_state = icon_on
on = 1
@@ -298,7 +345,7 @@
printpicture(user, P)
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
var/icon/photoimage = get_icon(turfs, target)
var/icon/photoimage = get_icon(turfs, target,user)
var/icon/small_img = icon(photoimage)
var/icon/tiny_img = icon(photoimage)
@@ -483,3 +530,15 @@
talk_into(M, msg)
for(var/mob/living/carbon/human/H in watcherslist)
H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1)
///hauntings, like hallucinations but more spooky
/obj/item/device/camera/proc/handle_haunt(mob/user as mob)
var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\
'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
user << pick(creepyasssounds)
+5 -5
View File
@@ -515,7 +515,7 @@
var/turf/T = get_turf(src)
var/obj/structure/cable/N = T.get_cable_node()
if (prob(50) && electrocute_mob(usr, N, N))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return
@@ -534,7 +534,7 @@
if(do_after(user, 50, target = src))
if(terminal && opened && has_electronics!=2)
if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return
@@ -654,7 +654,7 @@
var/mob/living/carbon/human/H = user
if(!isnull(H.internal_organs_by_name["cell"]) && H.a_intent == I_GRAB)
if(emagged || stat & BROKEN)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
H << "<span class='warning'>The APC power currents surge erratically, damaging your chassis!</span>"
@@ -1084,11 +1084,11 @@
cell.corrupt()
src.malfhack = 1
update_icon()
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
for(var/mob/M in viewers(src))
+1 -1
View File
@@ -182,7 +182,7 @@ By design, d1 is the smallest direction and d2 is the highest
if(!prob(prb))
return 0
if (electrocute_mob(user, powernet, src, siemens_coeff))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return 1
+1 -1
View File
@@ -102,7 +102,7 @@
// update icon overlays and power usage only if displayed level has changed
if(lastgen > powercap && prob(10))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
lastgen *= 0.5
+2 -2
View File
@@ -371,7 +371,7 @@
user << "You stick \the [W] into the light socket!"
if(has_power() && (W.flags & CONDUCT))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
//if(!user.mutations & RESIST_COLD)
@@ -521,7 +521,7 @@
if(status == LIGHT_OK || status == LIGHT_BURNED)
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
if(on)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
status = LIGHT_BROKEN
+1 -1
View File
@@ -196,7 +196,7 @@
A.dir = src.dir
playsound(get_turf(src), 'sound/weapons/emitter.ogg', 25, 1)
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
+16 -16
View File
@@ -13,7 +13,7 @@
icon_state = "smes"
density = 1
anchored = 1
var/capacity = 5e6 // maximum charge
var/charge = 0 // actual charge
@@ -52,7 +52,7 @@
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
spawn(5)
if(!powernet)
connect_to_network()
@@ -84,8 +84,8 @@
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
RefreshParts()
/obj/machinery/power/smes/RefreshParts()
var/IO = 0
var/C = 0
@@ -184,7 +184,7 @@
if(do_after(user, 50, target = src))
if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) //animate the electrocution if uncautious and unlucky
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return
@@ -200,7 +200,7 @@
//crowbarring it !
default_deconstruction_crowbar(I)
/obj/machinery/power/smes/disconnect_terminal()
if(terminal)
terminal.master = null
@@ -224,7 +224,7 @@
/obj/machinery/power/smes/proc/chargedisplay()
return round(5.5*charge/(capacity ? capacity : 5e6))
#define SMESRATE 0.05
#define SMESRATE 0.05
/obj/machinery/power/smes/process()
@@ -325,15 +325,15 @@
var/turf/T = get_turf(user)
var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one
if (prob(50) && electrocute_mob(user, N, N)) //animate the electrocution if uncautious and unlucky
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return
user.visible_message(\
"<span class='notice'>[user.name] adds the cables and connects the power terminal.</span>",\
"<span class='notice'>You add the cables and connect the power terminal.</span>")
terminal = new /obj/machinery/power/terminal(tempLoc)
terminal.dir = tempDir
terminal.master = src
@@ -375,7 +375,7 @@
data["outputLevel"] = output_level
data["outputMax"] = output_level_max
data["outputLoad"] = round(output_used)
if(outputting)
data["outputting"] = 2 // smes is outputting
else if(!outputting && output_attempt)
@@ -407,7 +407,7 @@
else if( href_list["online"] )
outputting(!output_attempt)
update_icon()
else if( href_list["input"] )
switch( href_list["input"] )
if("min")
@@ -438,7 +438,7 @@
for(var/mob/M in viewers(src))
M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2)
sleep(10*pick(4,5,6,7,10,14))
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
@@ -446,7 +446,7 @@
qdel(src)
return
if(prob(15)) //Power drain
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if(prob(50))
@@ -454,7 +454,7 @@
else
emp_act(2)
if(prob(5)) //smoke only
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
@@ -481,7 +481,7 @@
..()
/obj/machinery/power/smes/engineering
charge = 2e6 // Engineering starts with some charge for singulo
charge = 2e6 // Engineering starts with some charge for singulo
/obj/machinery/power/smes/magical
name = "magical power storage unit"
@@ -35,6 +35,24 @@
else
user.update_inv_r_hand()
/obj/item/weapon/gun/energy/gun/cyborg
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
/obj/item/weapon/gun/energy/gun/cyborg/process()
return 1
/obj/item/weapon/gun/energy/gun/cyborg/process_chambered()
if(in_chamber)
return 1
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell && R.cell.charge >= 83)
R.cell.use(83)
in_chamber = new projectile_type(src)
return 1
return 0
/obj/item/weapon/gun/energy/gun/mounted
name = "mounted energy gun"
self_recharge = 1
+1 -1
View File
@@ -122,7 +122,7 @@
/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user as mob)
do_teleport(user, user, 10)
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(10, 0, user.loc)
smoke.start()
charges--
@@ -21,7 +21,7 @@
/obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0)
if(!proj_hit)
if(!ismob(target) || blocked >= 2) //Fully blocked by mob or collided with dense object - burst into sparks!
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
proj_hit = 1
@@ -35,7 +35,7 @@
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
if(!proj_hit)
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread
var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
proj_hit = 1
+1 -1
View File
@@ -90,7 +90,7 @@
if(!stuff.anchored && stuff.loc)
teleammount++
do_teleport(stuff, stuff, 10)
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
smoke.set_up(max(round(10 - teleammount),1), 0, stuff.loc) //Smoke drops off if a lot of stuff is moved for the sake of sanity
smoke.start()

Some files were not shown because too many files have changed in this diff Show More