diff --git a/README.md b/README.md
index 1d0b30aa57a..108dd1c1602 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-/tg/station 13 v1.0 - 6 October 2010 [](http://hibernia.fallemmc.com:8090/job/tgstation/)
+/tg/station 13 v1.0 - 6 October 2010 [](https://travis-ci.org/tgstation/-tg-station)
Website: http://ss13.eu
diff --git a/_maps/map_files/tgstation.2.1.2.dmm b/_maps/map_files/tgstation.2.1.2.dmm
index 12fa7047b78..31e7f52d938 100644
--- a/_maps/map_files/tgstation.2.1.2.dmm
+++ b/_maps/map_files/tgstation.2.1.2.dmm
@@ -6415,7 +6415,7 @@
"cts" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 9},/area/syndicate_mothership)
"ctt" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/syndicate_mothership)
"ctu" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
-"ctv" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/beer{pixel_x = 3},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
+"ctv" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/beer{pixel_x = 5; pixel_y = -2; step_x = 0},/obj/item/toy/cards/deck/syndicate{icon_state = "deck_syndicate_full"; pixel_x = -6; pixel_y = 6},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"ctw" = (/obj/machinery/computer/telecrystals/uplinker,/turf/unsimulated/floor{tag = "icon-podhatch (WEST)"; icon_state = "podhatch"; dir = 8},/area/syndicate_mothership)
"ctx" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/syndicate_mothership)
"cty" = (/turf/unsimulated/floor,/area/syndicate_mothership)
@@ -8251,8 +8251,8 @@
"dcU" = (/obj/machinery/atmospherics/pipe/simple,/obj/structure/closet/crate/internals,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp)
"dcV" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp)
"dcW" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/machinery/camera{c_tag = "Labor Camp Storage"; dir = 8; network = list("Labor")},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp)
-"dcX" = (/obj/structure/table,/obj/item/toy/cards,/turf/simulated/floor,/area/security/prison)
-"dcY" = (/obj/structure/table/woodentable,/obj/item/toy/cards,/turf/simulated/floor,/area/crew_quarters/sleep)
+"dcX" = (/obj/structure/table,/obj/item/toy/cards/deck,/turf/simulated/floor,/area/security/prison)
+"dcY" = (/obj/structure/table/woodentable,/obj/item/toy/cards/deck,/turf/simulated/floor,/area/crew_quarters/sleep)
"dcZ" = (/obj/item/weapon/shard,/obj/item/weapon/module/power_control,/turf/simulated/floor/plating/airless,/area/AIsattele)
"dda" = (/obj/structure/computerframe,/turf/simulated/floor/plating/airless,/area/AIsattele)
"ddb" = (/obj/machinery/teleport/station,/turf/simulated/floor/plating/airless,/area/AIsattele)
diff --git a/_maps/tgstation2.dm b/_maps/tgstation2.dm
index 07acd427846..6f2eaa7c119 100644
--- a/_maps/tgstation2.dm
+++ b/_maps/tgstation2.dm
@@ -3,7 +3,7 @@
#include "map_files\tgstation.2.1.2.dmm"
#define MAP_FILE "tgstation.2.1.2.dmm"
- #define MAP_NAME "/tg/station 2"
+ #define MAP_NAME "TGstation 2"
#elif !defined(MAP_OVERRIDE)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 12ea157a3bc..91dfe014abb 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -7,7 +7,7 @@
/atom/proc/attackby(obj/item/W, mob/user)
return
/atom/movable/attackby(obj/item/W, mob/user)
- if(!(W.flags&NOBLUDGEON))
+ if(W && !(W.flags&NOBLUDGEON))
visible_message("[src] has been hit by [user] with [W].")
/mob/living/attackby(obj/item/I, mob/user)
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 8982f59174e..80f451fc871 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -265,6 +265,7 @@ client
if(isobj(D))
body += ""
if(isobj(D) || ismob(D) || isturf(D))
+ body += ""
body += ""
body += ""
@@ -634,6 +635,38 @@ client
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
+ else if(href_list["addreagent"])
+ if(!check_rights(0)) return
+
+ var/atom/A = locate(href_list["addreagent"])
+
+ if(!A.reagents)
+ var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num
+ if(amount)
+ A.create_reagents(amount)
+
+ if(A.reagents)
+ var/list/reagent_options = list()
+ for(var/r_id in chemical_reagents_list)
+ var/datum/reagent/R = chemical_reagents_list[r_id]
+ reagent_options[R.name] = r_id
+
+ if(reagent_options.len)
+ reagent_options = sortAssoc(reagent_options)
+ reagent_options.Insert(1, "CANCEL")
+
+ var/chosen = input(usr, "Choose a reagent to add.", "Choose a reagent.") in reagent_options
+ var/chosen_id = reagent_options[chosen]
+
+ if(chosen_id)
+ var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num
+ if(amount)
+ A.reagents.add_reagent(chosen_id, amount)
+ log_admin("[key_name(usr)] has added [amount] units of [chosen] to \the [A]")
+ message_admins("\blue [key_name(usr)] has added [amount] units of [chosen] to \the [A]")
+
+ href_list["datumrefresh"] = href_list["addreagent"]
+
else if(href_list["explode"])
if(!check_rights(R_FUN)) return
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index cd6c24c4c5d..3ccc010cdf1 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -447,6 +447,14 @@ var/list/uplink_items = list()
cost = 10
excludefrom = list(/datum/game_mode/nuclear)
+/datum/uplink_item/badass/syndiecards
+ name = "Syndicate Playing Cards"
+ desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, making them lethal weapons both when wielded as a blade and when thrown. \
+ You can also play card games with them."
+ item = /obj/item/toy/cards/deck/syndicate
+ cost = 1
+ excludefrom = list(/datum/game_mode/nuclear)
+
/datum/uplink_item/badass/balloon
name = "For showing that you are The Boss"
desc = "A useless red balloon with the syndicate logo on it, which can blow the deepest of covers."
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 1ab93c49bad..734a09218fb 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -280,6 +280,12 @@ var/list/blood_splatter_icons = list()
overlays += blood_splatter_icon
return 1 //we applied blood to the item
+/obj/item/clothing/gloves/add_blood(mob/living/carbon/M)
+ if(..() == 0) return 0
+ transfer_blood = rand(2, 4)
+ bloody_hands_mob = M
+ return 1
+
/turf/simulated/add_blood(mob/living/carbon/M)
if(..() == 0) return 0
@@ -291,6 +297,8 @@ var/list/blood_splatter_icons = list()
/mob/living/carbon/human/add_blood(mob/living/carbon/M)
if(..() == 0) return 0
add_blood_list(M)
+ bloody_hands = rand(2, 4)
+ bloody_hands_mob = M
update_inv_gloves() //handles bloody hands overlays and updating
return 1 //we applied blood to the item
diff --git a/code/game/dna.dm b/code/game/dna.dm
index 4e331c2d961..af35b1f9c5f 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -94,7 +94,7 @@
domutcheck(owner)
check_dna_integrity(owner)
- return owner.dna
+ return
/proc/check_dna_integrity(mob/living/carbon/character)
if(!(istype(character, /mob/living/carbon/human) || istype(character, /mob/living/carbon/monkey))) //Evict xenos from carbon 2012
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index 324205ea747..c56bbf0140d 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -45,6 +45,7 @@
attacktext = "hits"
attack_sound = 'sound/weapons/genhit1.ogg'
var/obj/effect/blob/factory/factory = null
+ var/is_zombie = 0
faction = "blob"
min_oxy = 0
max_oxy = 0
@@ -75,6 +76,36 @@
factory.spores += src
..()
+/mob/living/simple_animal/hostile/blobspore/Life()
+
+ if(!is_zombie)
+ for(var/mob/living/carbon/human/H in ListTargets(0)) //Only for people in the same tile
+ if(H.stat == DEAD)
+ Zombify(H)
+ break
+ ..()
+
+/mob/living/simple_animal/hostile/blobspore/proc/Zombify(var/mob/living/carbon/human/H)
+ if(H.wear_suit)
+ var/obj/item/clothing/suit/armor/A = H.wear_suit
+ if(A.armor && A.armor["melee"])
+ maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
+ maxHealth += 40
+ health = maxHealth
+ name = "blob zombie"
+ desc = "A shambling corpse animated by the blob."
+ melee_damage_lower = 10
+ melee_damage_upper = 15
+ icon = H.icon
+ icon_state = "husk_s"
+ H.hair_style = null
+ H.update_hair()
+ overlays = H.overlays
+ overlays += image('icons/mob/blob.dmi', icon_state = "blob_head")
+ H.loc = src
+ is_zombie = 1
+ loc.visible_message(" The corpse of [H.name] suddenly rises!")
+
/mob/living/simple_animal/hostile/blobspore/Die()
// On death, create a small smoke of harmful gas (s-Acid)
var/datum/effect/effect/system/chem_smoke_spread/S = new
@@ -94,4 +125,7 @@
/mob/living/simple_animal/hostile/blobspore/Del()
if(factory)
factory.spores -= src
+ if(contents)
+ for(var/mob/M in contents)
+ M.loc = src.loc
..()
diff --git a/code/game/gamemodes/changeling/changeling_mutations.dm b/code/game/gamemodes/changeling/changeling_mutations.dm
new file mode 100644
index 00000000000..52b55f82f98
--- /dev/null
+++ b/code/game/gamemodes/changeling/changeling_mutations.dm
@@ -0,0 +1,49 @@
+//This only contains the arm blade for now because I'm a lazy fuck. Yers truely, Miauw, resident lazy fuck.
+/obj/item/weapon/melee/arm_blade
+ name = "arm blade"
+ desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter"
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "arm_blade"
+ item_state = "arm_blade"
+ flags = ABSTRACT
+ w_class = 5.0
+ force = 25
+ throwforce = 0 //Just to be on the safe side
+ throw_range = 0
+ throw_speed = 0
+
+/obj/item/weapon/melee/arm_blade/New()
+ ..()
+ loc.visible_message("A grotesque blade forms around [name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!")
+
+/obj/item/weapon/melee/arm_blade/dropped(mob/user)
+ visible_message("With a sickening crunch, [user] reforms his blade into an arm!", "We assimilate our blade into our body", ""
+ return
+
+ else if(A.locked)
+ user << "The airlock's bolts prevent it from being forced."
+ return
+
+ else
+ //user.say("Heeeeeeeeeerrre's Johnny!")
+ user.visible_message("[user] forces the door to open with \his [src]!", "We force the door to open.", "You hear a metal screeching sound.")
+ A.open(1)
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index b0a2e6fa50e..93b04d157a3 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -118,12 +118,17 @@
changeling.absorb_dna(T)
if(src.nutrition < 400) src.nutrition = min((src.nutrition + T.nutrition), 400)
- if(T.mind && T.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points!
- changeling.chem_charges += min(T.mind.changeling.chem_charges, changeling.chem_storage)
- changeling.absorbedcount += T.mind.changeling.absorbedcount
- T.mind.changeling.absorbed_dna.len = 1
- T.mind.changeling.absorbedcount = 0
+ if(T.mind)//if the victim has got a mind
+
+ T.mind.show_memory(src, 0) //I can read your mind, kekeke. Output all their notes.
+
+ if(T.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points!
+ changeling.chem_charges += min(T.mind.changeling.chem_charges, changeling.chem_storage)
+ changeling.absorbedcount += T.mind.changeling.absorbedcount
+
+ T.mind.changeling.absorbed_dna.len = 1
+ T.mind.changeling.absorbedcount = 0
else
changeling.chem_charges += 10
@@ -156,8 +161,7 @@
changeling.chem_charges -= 5
changeling.geneticdamage = 3
- src.dna = chosen_dna
- src.real_name = chosen_dna.real_name
+ hardset_dna(src, chosen_dna.uni_identity, chosen_dna.struc_enzymes, chosen_dna.real_name, chosen_dna.mutantrace, chosen_dna.blood_type)
updateappearance(src)
domutcheck(src, null)
@@ -212,7 +216,7 @@
changeling.chem_charges -= 5
remove_changeling_powers()
src << "We transform our appearance."
- dna = chosen_dna
+ hardset_dna(src, chosen_dna.uni_identity, chosen_dna.struc_enzymes, chosen_dna.real_name, chosen_dna.mutantrace, chosen_dna.blood_type)
var/mob/living/carbon/human/O = humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPDAMAGE | TR_KEEPSRC),chosen_dna.real_name)
@@ -529,9 +533,34 @@ var/list/datum/dna/hivemind_bank = list()
if(src && src.mind && src.mind.changeling)
src.mind.changeling.mimicing = ""
- //////////
- //STINGS// //They get a pretty header because there's just so fucking many of them ;_;
- //////////
+
+/mob/living/carbon/proc/changeling_arm_blade()
+ set category = "Changeling"
+ set name = "Arm Blade (20)"
+
+ if(istype(l_hand, /obj/item/weapon/melee/arm_blade)) //Not the nicest way to do it, but eh
+ u_equip(l_hand)
+ return
+
+ if(istype(r_hand, /obj/item/weapon/melee/arm_blade))
+ u_equip(r_hand)
+ return
+
+ var/datum/changeling/changeling = changeling_power(20)
+ if(!changeling)
+ return
+
+ drop_item(get_active_hand())
+
+ put_in_hands(new /obj/item/weapon/melee/arm_blade(src))
+ changeling.geneticdamage += 6
+
+ changeling.chem_charges -= 20
+
+
+//////////
+//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
+//////////
/mob/living/carbon/proc/set_sting(A, icon, dna=null) //setting the sting and ui icon for it
src << "We prepare our sting, use alt+click on target to sting them."
@@ -584,15 +613,13 @@ var/list/datum/dna/hivemind_bank = list()
/mob/living/carbon/proc/sting_effect_trasnform(mob/living/carbon/T)
if(!sting_can_reach(T, 40))
return 0
- add_logs(src, T, "stung", object="transformation sting", addition="new identity is [src.mind.changeling.chosen_dna.real_name]")
+ add_logs(src, T, "stung", object="transformation sting", addition=" new identity is [src.mind.changeling.chosen_dna.real_name]")
if((HUSK in T.mutations) || !check_dna_integrity(T))
src << "Our sting appears ineffective against its DNA."
return 0
-
- T.dna = src.mind.changeling.chosen_dna
- T.real_name = src.mind.changeling.chosen_dna.real_name
+ var/datum/dna/NewDNA = src.mind.changeling.chosen_dna
+ hardset_dna(T, NewDNA.uni_identity, NewDNA.struc_enzymes, NewDNA.real_name, NewDNA.mutantrace, NewDNA.blood_type)
updateappearance(T)
- domutcheck(T, null)
feedback_add_details("changeling_powers","TS")
return 1
@@ -680,4 +707,4 @@ var/list/datum/dna/hivemind_bank = list()
T.reagents.add_reagent("ice", 30)
feedback_add_details("changeling_powers","CS")
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm
index 68450590a44..6c23082de16 100644
--- a/code/game/gamemodes/changeling/modularchangling.dm
+++ b/code/game/gamemodes/changeling/modularchangling.dm
@@ -161,6 +161,13 @@ var/list/powerinstances
allowduringlesserform = 1
verbpath = /mob/living/carbon/proc/changeling_mute_sting
+/datum/power/changeling/arm_blade
+ name = "Arm Blade"
+ desc = "We reform one of our arms into a deadly blade."
+ helptext = "Cannot be used while in lesser form."
+ genomecost = 1
+ allowduringlesserform = 0
+ verbpath = /mob/living/carbon/proc/changeling_arm_blade
// Modularchangling, totally stolen from the new player panel. YAYY
/datum/changeling/proc/EvolutionMenu()//The new one
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index ccec9e51165..bd50deb227b 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -226,12 +226,18 @@ var/list/sacrificed = list()
seer()
if(usr.loc==src.loc)
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!")
- if(usr.see_invisible!=0 && usr.see_invisible!=15)
- usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision."
+ var/mob/living/carbon/human/user = usr
+ if(user.see_invisible!=25 || (istype(user) && user.glasses)) //check for non humans
+ user << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision."
else
- usr << "\red The world beyond opens to your eyes."
- usr.see_invisible = SEE_INVISIBLE_OBSERVER
- usr.seer = 1
+ user << "\red The world beyond opens to your eyes."
+ var/see_temp = user.see_invisible
+ user.see_invisible = SEE_INVISIBLE_OBSERVER
+ user.seer = 1
+ while(user.loc==src.loc)
+ sleep(30)
+ user.seer = 0
+ user.see_invisible = see_temp
return
return fizzle()
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 396050ca1c2..cc6f9549400 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -158,6 +158,11 @@
A.blob_act()
del(src)
+/obj/machinery/sleeper/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise
+ if(M.environment_smash)
+ visible_message("[M.name] smashes [src] apart!")
+ del(src)
+ return
/obj/machinery/sleeper/attackby(obj/item/I, mob/user)
if(!istype(I, /obj/item/weapon/grab))
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index 6479c5d9344..16e85a4b41b 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -261,7 +261,7 @@
T.temperature = 5000
T.hotspot_expose(50000,50000,1)
if(L.name=="Holocarp Spawn")
- new /mob/living/simple_animal/hostile/carp(L.loc)
+ new /mob/living/simple_animal/hostile/carp/holocarp(L.loc)
/obj/machinery/computer/HolodeckControl/proc/emergencyShutdown()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 0339f223bf7..d17cb57fa7a 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -13,10 +13,20 @@
/obj/machinery/computer/aifixer/attackby(I as obj, user as mob)
+ if(occupant && istype(I, /obj/item/weapon/screwdriver))
+ if(stat & (NOPOWER|BROKEN))
+ user << "The screws on [name]'s screen won't budge."
+ else
+ user << "The screws on [name]'s screen won't budge and it emits a warning beep."
+ return
if(istype(I, /obj/item/device/aicard))
var/obj/item/device/aicard/AIcard = I
if(stat & (NOPOWER|BROKEN))
+ if(occupant)
+ AIcard.transfer_ai("AIFIXER","AICARD",src,user)
+ overlays.Cut()
+ return
user << "This terminal isn't functioning right now, get it working!"
return
AIcard.transfer_ai("AIFIXER","AICARD",src,user)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 39e5691e208..92ea6494e8d 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -23,7 +23,7 @@
/obj/item/toy/prize/mauler = 1,
/obj/item/toy/prize/odysseus = 1,
/obj/item/toy/prize/phazon = 1,
- /obj/item/toy/cards = 2,
+ /obj/item/toy/cards/deck = 2,
/obj/item/toy/nuke = 2
)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index b04ecad5106..721081f90fb 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -487,7 +487,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
for(var/datum/feed_channel/F in news_network.network_channels)
if( (!F.locked || F.author == scanned_user) && !F.censored)
available_channels += F.channel_name
- src.channel_name = strip_html(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
+ src.channel_name = strip_html_simple(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
src.updateUsrDialog()
else if(href_list["set_new_message"])
diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm
index 08cf736db77..18754297e12 100644
--- a/code/game/objects/effects/gibs.dm
+++ b/code/game/objects/effects/gibs.dm
@@ -1,14 +1,14 @@
/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA)
- new /obj/effect/gibspawner/generic(get_turf(location),viruses,MobDNA)
+ new /obj/effect/gibspawner/generic(location,viruses,MobDNA)
/proc/hgibs(atom/location, var/list/viruses, var/datum/dna/MobDNA)
- new /obj/effect/gibspawner/human(get_turf(location),viruses,MobDNA)
+ new /obj/effect/gibspawner/human(location,viruses,MobDNA)
/proc/xgibs(atom/location, var/list/viruses)
- new /obj/effect/gibspawner/xeno(get_turf(location),viruses)
+ new /obj/effect/gibspawner/xeno(location,viruses)
/proc/robogibs(atom/location, var/list/viruses)
- new /obj/effect/gibspawner/robot(get_turf(location),viruses)
+ new /obj/effect/gibspawner/robot(location,viruses)
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib()
@@ -20,8 +20,7 @@
New(location, var/list/viruses, var/datum/dna/MobDNA)
..()
- if(istype(loc,/turf)) //basically if a badmin spawns it
- Gib(loc,viruses,MobDNA)
+ Gib(loc,viruses,MobDNA)
proc/Gib(atom/location, var/list/viruses = list(), var/datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
@@ -43,6 +42,9 @@
for(var/j = 1, j<= gibamounts[i], j++)
var/gibType = gibtypes[i]
gib = new gibType(location)
+ if(istype(location,/mob/living/carbon))
+ var/mob/living/carbon/digester = location
+ digester.stomach_contents += gib
if(viruses.len > 0)
for(var/datum/disease/D in viruses)
@@ -59,7 +61,8 @@
else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
var/list/directions = gibdirections[i]
- if(directions.len)
- gib.streak(directions)
+ if(istype(loc,/turf))
+ if(directions.len)
+ gib.streak(directions)
del(src)
\ No newline at end of file
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 91b91f4332f..e65456e7e41 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -7,6 +7,8 @@
var/burn_point = null
var/burning = null
var/hitsound = null
+ var/throwhitsound = null
+ var/throwtapsound = 'sound/weapons/throwtap.ogg'
var/w_class = 3.0
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
pass_flags = PASSTABLE
@@ -556,4 +558,5 @@
/obj/item/clothing/gloves/clean_blood()
. = ..()
if(.)
- transfer_blood = 0
\ No newline at end of file
+ transfer_blood = 0
+ bloody_hands_mob = null
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 94ca43fb9bc..7a3f1645432 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -566,15 +566,34 @@
obj/item/toy/cards
- name = "deck of cards"
- desc = "A deck of space-grade playing cards."
- icon = 'icons/obj/toy.dmi'
- icon_state = "deck_full"
- w_class = 2.0
- var/list/cards = list()
+ var/parentdeck = null
+ var/deckstyle = "nanotrasen"
+ var/card_hitsound = null
+ var/card_force = 0
+ var/card_throwforce = 0
+ var/card_throw_speed = 4
+ var/card_throw_range = 20
+ var/list/card_attack_verb = list("attacked")
obj/item/toy/cards/New()
..()
+
+obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck
+ if(!istype(sourceobj))
+ return
+
+obj/item/toy/cards/deck
+ name = "deck of cards"
+ desc = "A deck of space-grade playing cards."
+ icon = 'icons/obj/toy.dmi'
+ deckstyle = "nanotrasen"
+ icon_state = "deck_nanotrasen_full"
+ w_class = 2.0
+ var/list/cards = list()
+
+obj/item/toy/cards/deck/New()
+ ..()
+ icon_state = "deck_[deckstyle]_full"
for(var/i = 2; i <= 10; i++)
cards += "[i] of Hearts"
cards += "[i] of Spades"
@@ -598,33 +617,35 @@ obj/item/toy/cards/New()
cards += "Ace of Diamonds"
-obj/item/toy/cards/attack_hand(mob/user as mob)
+obj/item/toy/cards/deck/attack_hand(mob/user as mob)
var/choice = null
if(cards.len == 0)
- src.icon_state = "deck_empty"
+ src.icon_state = "deck_[deckstyle]_empty"
user << "There are no more cards to draw."
return
- var/obj/item/toy/singlecard/H = new/obj/item/toy/singlecard(user.loc)
+ var/obj/item/toy/cards/singlecard/H = new/obj/item/toy/cards/singlecard(user.loc)
choice = cards[1]
H.cardname = choice
H.parentdeck = src
+ var/O = src
+ H.apply_card_vars(H,O)
src.cards -= choice
H.pickup(user)
user.put_in_active_hand(H)
src.visible_message("[user] draws a card from the deck.", "You draw a card from the deck.")
if(cards.len > 26)
- src.icon_state = "deck_full"
+ src.icon_state = "deck_[deckstyle]_full"
else if(cards.len > 10)
- src.icon_state = "deck_half"
+ src.icon_state = "deck_[deckstyle]_half"
else if(cards.len > 1)
- src.icon_state = "deck_low"
+ src.icon_state = "deck_[deckstyle]_low"
-obj/item/toy/cards/attack_self(mob/user as mob)
+obj/item/toy/cards/deck/attack_self(mob/user as mob)
cards = shuffle(cards)
playsound(user, 'sound/items/cardshuffle.ogg', 50, 1)
user.visible_message("[user] shuffles the deck.", "You shuffle the deck.")
-obj/item/toy/cards/attackby(obj/item/toy/singlecard/C, mob/living/user)
+obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/user)
..()
if(istype(C))
if(C.parentdeck == src)
@@ -635,14 +656,14 @@ obj/item/toy/cards/attackby(obj/item/toy/singlecard/C, mob/living/user)
else
user << "You can't mix cards from other decks."
if(cards.len > 26)
- src.icon_state = "deck_full"
+ src.icon_state = "deck_[deckstyle]_full"
else if(cards.len > 10)
- src.icon_state = "deck_half"
+ src.icon_state = "deck_[deckstyle]_half"
else if(cards.len > 1)
- src.icon_state = "deck_low"
+ src.icon_state = "deck_[deckstyle]_low"
-obj/item/toy/cards/attackby(obj/item/toy/cardhand/C, mob/living/user)
+obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user)
..()
if(istype(C))
if(C.parentdeck == src)
@@ -653,13 +674,13 @@ obj/item/toy/cards/attackby(obj/item/toy/cardhand/C, mob/living/user)
else
user << "You can't mix cards from other decks."
if(cards.len > 26)
- src.icon_state = "deck_full"
+ src.icon_state = "deck_[deckstyle]_full"
else if(cards.len > 10)
- src.icon_state = "deck_half"
+ src.icon_state = "deck_[deckstyle]_half"
else if(cards.len > 1)
- src.icon_state = "deck_low"
+ src.icon_state = "deck_[deckstyle]_low"
-obj/item/toy/cards/MouseDrop(atom/over_object)
+obj/item/toy/cards/deck/MouseDrop(atom/over_object)
var/mob/M = usr
if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained())
return
@@ -683,22 +704,21 @@ obj/item/toy/cards/MouseDrop(atom/over_object)
-obj/item/toy/cardhand
+obj/item/toy/cards/cardhand
name = "hand of cards"
desc = "A number of cards not in a deck, customarily held in ones hand."
icon = 'icons/obj/toy.dmi'
- icon_state = "hand2"
+ icon_state = "nanotrasen_hand2"
w_class = 1.0
var/list/currenthand = list()
- var/obj/item/toy/cards/parentdeck = null
var/choice = null
-obj/item/toy/cardhand/attack_self(mob/user as mob)
+obj/item/toy/cards/cardhand/attack_self(mob/user as mob)
user.set_machine(src)
interact(user)
-obj/item/toy/cardhand/interact(mob/user)
+obj/item/toy/cards/cardhand/interact(mob/user)
var/dat = "You have:
"
for(var/t in currenthand)
dat += "A [t].
"
@@ -709,36 +729,37 @@ obj/item/toy/cardhand/interact(mob/user)
popup.open()
-obj/item/toy/cardhand/Topic(href, href_list)
+obj/item/toy/cards/cardhand/Topic(href, href_list)
if(..())
return
if(usr.stat || !ishuman(usr) || !usr.canmove)
return
var/mob/living/carbon/human/cardUser = usr
+ var/O = src
if(href_list["pick"])
if (cardUser.get_item_by_slot(slot_l_hand) == src || cardUser.get_item_by_slot(slot_r_hand) == src)
var/choice = href_list["pick"]
- var/obj/item/toy/singlecard/C = new/obj/item/toy/singlecard(cardUser.loc)
+ var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc)
src.currenthand -= choice
C.parentdeck = src.parentdeck
C.cardname = choice
+ C.apply_card_vars(C,O)
C.pickup(cardUser)
cardUser.put_in_any_hand_if_possible(C)
cardUser.visible_message("[cardUser] draws a card from \his hand.", "You take the [C.cardname] from your hand.")
interact(cardUser)
-
if(src.currenthand.len < 3)
- src.icon_state = "hand2"
+ src.icon_state = "[deckstyle]_hand2"
else if(src.currenthand.len < 4)
- src.icon_state = "hand3"
+ src.icon_state = "[deckstyle]_hand3"
else if(src.currenthand.len < 5)
- src.icon_state = "hand4"
-
+ src.icon_state = "[deckstyle]_hand4"
if(src.currenthand.len == 1)
- var/obj/item/toy/singlecard/N = new/obj/item/toy/singlecard(src.loc)
+ var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(src.loc)
N.parentdeck = src.parentdeck
N.cardname = src.currenthand[1]
+ N.apply_card_vars(N,O)
cardUser.u_equip(src)
N.pickup(cardUser)
cardUser.put_in_any_hand_if_possible(N)
@@ -747,7 +768,7 @@ obj/item/toy/cardhand/Topic(href, href_list)
del(src)
return
-obj/item/toy/cardhand/attackby(obj/item/toy/singlecard/C, mob/living/user)
+obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user)
if(istype(C))
if(C.parentdeck == src.parentdeck)
src.currenthand += C.cardname
@@ -755,31 +776,39 @@ obj/item/toy/cardhand/attackby(obj/item/toy/singlecard/C, mob/living/user)
user.visible_message("[user] adds a card to their hand.", "You add the [C.cardname] to your hand.")
interact(user)
if(currenthand.len > 4)
- src.icon_state = "hand5"
+ src.icon_state = "[deckstyle]_hand5"
else if(currenthand.len > 3)
- src.icon_state = "hand4"
+ src.icon_state = "[deckstyle]_hand4"
else if(currenthand.len > 2)
- src.icon_state = "hand3"
+ src.icon_state = "[deckstyle]_hand3"
del(C)
else
user << "You can't mix cards from other decks."
+obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/toy/cards/sourceobj)
+ ..()
+ newobj.deckstyle = sourceobj.deckstyle
+ newobj.icon_state = "[deckstyle]_hand2" // Another dumb hack, without this the hand is invisible (or has the default deckstyle) until another card is added.
+ newobj.card_hitsound = sourceobj.card_hitsound
+ newobj.card_force = sourceobj.card_force
+ newobj.card_throwforce = sourceobj.card_throwforce
+ newobj.card_throw_speed = sourceobj.card_throw_speed
+ newobj.card_throw_range = sourceobj.card_throw_range
+ newobj.card_attack_verb = sourceobj.card_attack_verb
-
-
-obj/item/toy/singlecard
+obj/item/toy/cards/singlecard
name = "card"
desc = "a card"
icon = 'icons/obj/toy.dmi'
- icon_state = "singlecard_down"
+ icon_state = "singlecard_nanotrasen_down"
w_class = 1.0
var/cardname = null
- var/obj/item/toy/cards/parentdeck = null
var/flipped = 0
pixel_x = -5
-obj/item/toy/singlecard/examine()
+
+obj/item/toy/cards/singlecard/examine()
set src in usr.contents
if(ishuman(usr))
var/mob/living/carbon/human/cardUser = usr
@@ -789,7 +818,7 @@ obj/item/toy/singlecard/examine()
cardUser << "You need to have the card in your hand to check it."
-obj/item/toy/singlecard/verb/Flip()
+obj/item/toy/cards/singlecard/verb/Flip()
set name = "Flip Card"
set category = "Object"
set src in range(1)
@@ -798,26 +827,27 @@ obj/item/toy/singlecard/verb/Flip()
if(!flipped)
src.flipped = 1
if (cardname)
- src.icon_state = "sc_[cardname]"
+ src.icon_state = "sc_[cardname]_[deckstyle]"
src.name = src.cardname
else
- src.icon_state = "sc_Ace of Spades"
+ src.icon_state = "sc_Ace of Spades_[deckstyle]"
src.name = "What Card"
src.pixel_x = 5
else if(flipped)
src.flipped = 0
- src.icon_state = "singlecard_down"
+ src.icon_state = "singlecard_down_[deckstyle]"
src.name = "card"
src.pixel_x = -5
-obj/item/toy/singlecard/attackby(obj/item/I, mob/living/user)
- if(istype(I, /obj/item/toy/singlecard/))
- var/obj/item/toy/singlecard/C = I
+obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user)
+ if(istype(I, /obj/item/toy/cards/singlecard/))
+ var/obj/item/toy/cards/singlecard/C = I
if(C.parentdeck == src.parentdeck)
- var/obj/item/toy/cardhand/H = new/obj/item/toy/cardhand(user.loc)
+ var/obj/item/toy/cards/cardhand/H = new/obj/item/toy/cards/cardhand(user.loc)
H.currenthand += C.cardname
H.currenthand += src.cardname
H.parentdeck = C.parentdeck
+ H.apply_card_vars(H,C)
user.u_equip(C)
H.pickup(user)
user.put_in_active_hand(H)
@@ -827,29 +857,62 @@ obj/item/toy/singlecard/attackby(obj/item/I, mob/living/user)
else
user << "You can't mix cards from other decks."
- if(istype(I, /obj/item/toy/cardhand/))
- var/obj/item/toy/cardhand/H = I
+ if(istype(I, /obj/item/toy/cards/cardhand/))
+ var/obj/item/toy/cards/cardhand/H = I
if(H.parentdeck == parentdeck)
H.currenthand += cardname
user.u_equip(src)
user.visible_message("[user] adds a card to \his hand.", "You add the [cardname] to your hand.")
H.interact(user)
if(H.currenthand.len > 4)
- H.icon_state = "hand5"
+ H.icon_state = "[deckstyle]_hand5"
else if(H.currenthand.len > 3)
- H.icon_state = "hand4"
+ H.icon_state = "[deckstyle]_hand4"
else if(H.currenthand.len > 2)
- H.icon_state = "hand3"
+ H.icon_state = "[deckstyle]_hand3"
del(src)
else
user << "You can't mix cards from other decks."
-obj/item/toy/singlecard/attack_self(mob/user)
+obj/item/toy/cards/singlecard/attack_self(mob/user)
if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained())
return
Flip()
+obj/item/toy/cards/singlecard/apply_card_vars(obj/item/toy/cards/singlecard/newobj,obj/item/toy/cards/sourceobj)
+ ..()
+ newobj.deckstyle = sourceobj.deckstyle
+ newobj.icon_state = "singlecard_down_[deckstyle]" // Without this the card is invisible until flipped. It's an ugly hack, but it works.
+ newobj.card_hitsound = sourceobj.card_hitsound
+ newobj.hitsound = newobj.card_hitsound
+ newobj.card_force = sourceobj.card_force
+ newobj.force = newobj.card_force
+ newobj.card_throwforce = sourceobj.card_throwforce
+ newobj.throwforce = newobj.card_throwforce
+ newobj.card_throw_speed = sourceobj.card_throw_speed
+ newobj.throw_speed = newobj.card_throw_speed
+ newobj.card_throw_range = sourceobj.card_throw_range
+ newobj.throw_range = newobj.card_throw_range
+ newobj.card_attack_verb = sourceobj.card_attack_verb
+ newobj.attack_verb = newobj.card_attack_verb
+
+
+/*
+|| Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. ||
+*/
+
+obj/item/toy/cards/deck/syndicate
+ name = "suspicious looking deck of cards"
+ desc = "A deck of space-grade playing cards. They seem unusually rigid."
+ deckstyle = "syndicate"
+ card_hitsound = 'sound/weapons/bladeslice.ogg'
+ card_force = 15
+ card_throwforce = 15
+ card_throw_speed = 6
+ card_throw_range = 20
+ card_attack_verb = list("attacked", "sliced", "diced", "slashed", "cut")
+
/obj/item/toy/nuke
name = "\improper Nuclear Fission Explosive toy"
@@ -879,4 +942,3 @@ obj/item/toy/singlecard/attack_self(mob/user)
-
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 7ad0e51004d..8b952863b53 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -162,6 +162,24 @@
..()
+/obj/item/weapon/weldingtool/attack(mob/living/carbon/human/H, mob/user)
+ var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
+
+ if(istype(H))
+ if(affecting.status == ORGAN_ROBOTIC)
+ if(src.remove_fuel(0))
+ src.item_heal_robotic(H, user, 30, 0)
+ return
+ else
+ user << "Need more welding fuel!"
+ return
+ else
+ return ..()
+
+ else
+ return ..()
+
+
/obj/item/weapon/weldingtool/process()
switch(welding)
if(0)
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index bd619d21103..19ad56eb441 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -115,6 +115,32 @@
if(!I) return 0
return I.IsShield()
+///////////Two hand required objects///////////////
+//This is for objects that require two hands to even pick up
+/obj/item/weapon/twohanded/required/
+ w_class = 5.0
+
+/obj/item/weapon/twohanded/required/attack_self()
+ return
+
+/obj/item/weapon/twohanded/required/mob_can_equip(M as mob, slot)
+ if(wielded)
+ M << "[src.name] is too cumbersome to carry with anything but your hands!"
+ return 0
+ return ..()
+
+/obj/item/weapon/twohanded/required/attack_hand(mob/user)//Can't even pick it up without both hands empty
+ var/obj/item/weapon/twohanded/required/H = user.get_inactive_hand()
+ if(H != null)
+ user.visible_message("[src.name] is too cumbersome to carry in one hand!")
+ return
+ var/obj/item/weapon/twohanded/offhand/O = new(user)
+ user.put_in_inactive_hand(O)
+ ..()
+ wielded = 1
+
+
+obj/item/weapon/twohanded/
/*
* Fireaxe
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 3696c7196c3..e19bc36be1c 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -148,7 +148,7 @@
return
/obj/structure/closet/attack_animal(mob/living/simple_animal/user as mob)
- if(user.wall_smash)
+ if(user.environment_smash)
visible_message("\red [user] destroys the [src]. ")
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm
index 24a84fb13e3..fc5ba425f09 100644
--- a/code/game/objects/structures/crates_lockers/closets/statue.dm
+++ b/code/game/objects/structures/crates_lockers/closets/statue.dm
@@ -102,7 +102,7 @@
return
/obj/structure/closet/statue/attack_animal(mob/living/simple_animal/user as mob)
- if(user.wall_smash)
+ if(user.environment_smash)
for(var/mob/M in src)
shatter(M)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index ea2d0125f17..d5e6f0bc2f5 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -30,6 +30,11 @@
manual_unbuckle(user)
return
+/obj/structure/stool/bed/attack_animal(var/mob/living/simple_animal/M)//No more buckling hostile mobs to chairs to render them immobile forever
+ if(M.environment_smash)
+ new /obj/item/stack/sheet/metal(src.loc)
+ del(src)
+
/obj/structure/stool/bed/MouseDrop_T(mob/M as mob, mob/user as mob)
if(!istype(M)) return
buckle_mob(M, user)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index c1f750e0aa6..dec6da93d5b 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -228,7 +228,7 @@
/obj/structure/table/attack_animal(mob/living/simple_animal/user)
- if(user.wall_smash)
+ if(user.environment_smash)
visible_message("[user] smashes [src] apart!")
if(istype(src, /obj/structure/table/reinforced))
new /obj/item/weapon/table_parts/reinforced(loc)
@@ -310,7 +310,8 @@
playsound(src.loc, "sparks", 50, 1)
table_destroy(1, user)
- user.drop_item(src)
+ if(!(((I.flags & ABSTRACT)))) //WE NEED MORE PAREMS
+ user.drop_item(src)
/obj/structure/table/proc/table_destroy(var/destroy_type, var/mob/user as mob)
@@ -492,7 +493,7 @@ Destroy type values:
/obj/structure/rack/attack_animal(mob/living/simple_animal/user)
- if(user.wall_smash)
+ if(user.environment_smash)
visible_message("[user] smashes [src] apart!")
new /obj/item/weapon/rack_parts(loc)
density = 0
diff --git a/code/game/sound.dm b/code/game/sound.dm
index eed7b1c3bed..59ff419701f 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -68,6 +68,7 @@ var/const/SURROUND_CAP = 7
if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg')
if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
+ if ("bodyfall") soundin = pick('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg')
if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')
if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index ad5aa43c8a0..daa296bb4a5 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -101,23 +101,18 @@
return src.attack_hand(user)
-
-/turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob)
- if(M.wall_smash)
- if (istype(src, /turf/simulated/wall/r_wall))
- M << text("\blue This wall is far too strong for you to destroy.")
- return
- else
- if (prob(40))
- M << text("\blue You smash through the wall.")
+/turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M)
+ if(M.environment_smash >= 2)
+ if(istype(src, /turf/simulated/wall/r_wall))
+ if(M.environment_smash == 3)
dismantle_wall(1)
- return
+ M << "You smash through the wall."
else
- M << text("\blue You smash against the wall.")
- return
-
- M << "\blue You push the wall but nothing happens!"
- return
+ M << "This wall is far too strong for you to destroy."
+ else
+ M << "You smash through the wall."
+ dismantle_wall(1)
+ return
/turf/simulated/wall/attack_hand(mob/user as mob)
if (HULK in user.mutations)
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index dba6665297e..58bce47400a 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -16,7 +16,7 @@ world/IsBanned(key,address,computer_id)
diary << "Ban database connection failure. Admin [ckeytext] not checked"
return
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_Ban WHERE (ckey = '[ckeytext]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = '[ckeytext]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
query.Execute()
@@ -80,7 +80,7 @@ world/IsBanned(key,address,computer_id)
failedcid = 0
cidquery = " OR computerid = '[computer_id]' "
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_Ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
query.Execute()
@@ -107,4 +107,4 @@ world/IsBanned(key,address,computer_id)
message_admins("[key] has logged in with a blank computer id in the ban check.")
if (failedip)
message_admins("[key] has logged in with a blank ip in the ban check.")
- return ..() //default pager ban stuff
\ No newline at end of file
+ return ..() //default pager ban stuff
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index a5ff7f12801..e4ca1654bde 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -5,10 +5,10 @@ atom/var/list/suit_fibers
atom/proc/add_fibers(mob/living/carbon/human/M)
if(M.gloves && istype(M.gloves,/obj/item/clothing/))
var/obj/item/clothing/gloves/G = M.gloves
- if(G.transfer_blood) //bloodied gloves transfer blood to touched objects
+ if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
if(add_blood(G.bloody_hands_mob)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
G.transfer_blood--
- else if(M.bloody_hands)
+ else if(M.bloody_hands > 1)
if(add_blood(M.bloody_hands_mob))
M.bloody_hands--
if(!suit_fibers) suit_fibers = list()
diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm
index bc55934b5ba..9d9fd3a8e95 100644
--- a/code/modules/detectivework/footprints_and_rag.dm
+++ b/code/modules/detectivework/footprints_and_rag.dm
@@ -2,7 +2,6 @@
/mob
var/bloody_hands = 0
var/mob/living/carbon/human/bloody_hands_mob
- var/mob/living/carbon/human/track_blood_mob
/obj/item/clothing/gloves
var/transfer_blood = 0
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 52d9047d294..16e24a3fd64 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -4,7 +4,7 @@
name = "ore redemption machine"
desc = "A machine that accepts ore and instantly transforms it into workable material sheets, but cannot produce alloys such as Plasteel. Points for ore are generated based on type and can be redeemed at a mining equipment locker."
icon = 'icons/obj/machines/mining_machines.dmi'
- icon_state = "stacker"
+ icon_state = "ore_redemption"
density = 1
anchored = 1.0
var/obj/machinery/mineral/stacking_unit_console/CONSOLE
@@ -62,8 +62,8 @@
var/obj/item/stack/sheet/mineral/gold/M = new /obj/item/stack/sheet/mineral/gold(src)
return M
if(istype(O, /obj/item/weapon/ore/plasma))
- var/obj/item/stack/sheet/mineral/plasma/M = new /obj/item/stack/sheet/mineral/plasma(src)
points += 10
+ var/obj/item/stack/sheet/mineral/plasma/M = new /obj/item/stack/sheet/mineral/plasma(src)
return M
if(istype(O, /obj/item/weapon/ore/glass))
points += 1
@@ -155,21 +155,18 @@
var/obj/item/weapon/card/id/inserted_id
var/list/prize_list = list(
new /datum/data/mining_equipment("Chili", /obj/item/weapon/reagent_containers/food/snacks/hotchili, 100),
- new /datum/data/mining_equipment("Salad", /obj/item/weapon/reagent_containers/food/snacks/validsalad, 300),
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 500),
new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/cigarette/cigar/havana, 500),
new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 500),
- new /datum/data/mining_equipment("Stimulant Pills", /obj/item/weapon/storage/pill_bottle/stimulant, 700),
- new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 1000),
- new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 1500),
- new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c500, 5000),
- new /datum/data/mining_equipment("Multitool", /obj/item/device/multitool, 100),
- new /datum/data/mining_equipment("Toolbox", /obj/item/weapon/storage/toolbox/mechanical, 300),
- new /datum/data/mining_equipment("Pickaxe", /obj/item/weapon/pickaxe, 100),
+ new /datum/data/mining_equipment("Stimulant pills", /obj/item/weapon/storage/pill_bottle/stimulant, 700),
+ new /datum/data/mining_equipment("Alien toy", /obj/item/clothing/mask/facehugger/toy, 1000),
+ new /datum/data/mining_equipment("Laser pointer", /obj/item/device/laser_pointer, 1500),
+ new /datum/data/mining_equipment("Space cash", /obj/item/weapon/spacecash/c500, 5000),
new /datum/data/mining_equipment("Drill", /obj/item/weapon/pickaxe/drill, 500),
- new /datum/data/mining_equipment("Jackhammer", /obj/item/weapon/pickaxe/jackhammer, 1000),
- new /datum/data/mining_equipment("Wormhole Jaunter", /obj/item/device/wormhole_jaunter, 1000),
- new /datum/data/mining_equipment("Blast Shield", /obj/item/weapon/shield/riot/mining, 2000),
+ new /datum/data/mining_equipment("Sonic Jackhammer", /obj/item/weapon/pickaxe/jackhammer, 1000),
+ new /datum/data/mining_equipment("Jaunter", /obj/item/device/wormhole_jaunter, 1000),
+ new /datum/data/mining_equipment("Resonator", /obj/item/weapon/resonator, 1500),
+ new /datum/data/mining_equipment("Kinetic accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 2500),
new /datum/data/mining_equipment("Jetpack", /obj/item/weapon/tank/jetpack/carbondioxide, 5000),)
/datum/data/mining_equipment/
@@ -239,8 +236,8 @@
/obj/item/device/wormhole_jaunter
name = "wormhole jaunter"
desc = "A single use device harnessing outdated wormhole technology, Nanotrasen has since turned its eyes to blue space for more accurate teleportation. The wormholes it creates are unpleasant to travel through, to say the least."
- icon = 'icons/obj/device.dmi'
- icon_state = "hand_tele"
+ icon = 'icons/obj/items.dmi'
+ icon_state = "Jaunter"
item_state = "electronic"
throwforce = 0
w_class = 2.0
@@ -267,10 +264,13 @@
var/obj/effect/portal/wormhole/jaunt_tunnel/J = new /obj/effect/portal/wormhole/jaunt_tunnel(get_turf(src), chosen_beacon, lifespan=100)
J.target = chosen_beacon
try_move_adjacent(J)
+ playsound(src,'sound/effects/sparks4.ogg',50,1)
del(src)
/obj/effect/portal/wormhole/jaunt_tunnel
name = "jaunt tunnel"
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "bhole3"
desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon."
/obj/effect/portal/wormhole/jaunt_tunnel/teleport(atom/movable/M)
@@ -291,17 +291,73 @@
T.add_vomit_floor(L)
playsound(L, 'sound/effects/splat.ogg', 50, 1)
-//Mining Blast Shield
-/obj/item/weapon/shield/riot/mining
- name = "blast shield"
- desc = "Originally conceived as an attempt to protect miners from gibtonite explosions, these shields are much more effective at protecting miners from hostile wildlife on the asteroid."
+//Mining Resonator
+
+/obj/item/weapon/resonator
+ name = "resonator"
+ icon = 'icons/obj/items.dmi'
+ icon_state = "resonator"
+ item_state = "resonator"
+ desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in a vaccuum."
+ w_class = 3
+ force = 10
+ throwforce = 10
+ var/cooldown = 0
+
+/obj/item/weapon/resonator/proc/CreateResonance(var/target)
+ if(cooldown <= 0)
+ playsound(src,'sound/effects/stealthoff.ogg',50,1)
+ new /obj/effect/resonance(get_turf(target))
+ cooldown = 1
+ spawn(25)
+ cooldown = 0
+
+/obj/item/weapon/resonator/attack_self(mob/user as mob)
+ CreateResonance(src)
+ ..()
+
+/obj/item/weapon/resonator/attack(var/atom/A)
+ CreateResonance(A)
+ ..()
+
+/obj/effect/resonance
+ name = "resonance field"
+ desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "shield1"
+ layer = 4.1
+ mouse_opacity = 0
+ var/resonance_damage = 30
+
+/obj/effect/resonance/New()
+ var/turf/proj_turf = get_turf(src)
+ if(!istype(proj_turf, /turf))
+ return
+ if(istype(proj_turf, /turf/simulated/mineral))
+ var/turf/simulated/mineral/M = proj_turf
+ playsound(src,'sound/effects/sparks4.ogg',50,1)
+ M.gets_drilled()
+ spawn(5)
+ del(src)
+ else
+ var/datum/gas_mixture/environment = proj_turf.return_air()
+ var/pressure = environment.return_pressure()
+ if(pressure < 50)
+ name = "strong resonance"
+ resonance_damage = 60
+ spawn(50)
+ playsound(src,'sound/effects/sparks4.ogg',50,1)
+ for(var/mob/living/L in src.loc)
+ L << "The [src.name] ruptured with you in it!"
+ L.adjustBruteLoss(resonance_damage)
+ del(src)
//Fakehugger Toy
/obj/item/clothing/mask/facehugger/toy
- desc = "A commemorative toy often used to play pranks on other miners by putting it in their beds. It takes a bit to recharge after latching onto something."
+ desc = "A toy often used to play pranks on other miners by putting it in their beds. It takes a bit to recharge after latching onto something."
throwforce = 0
sterile = 1
- tint = 3
+ tint = 3 //Makes it feel more authentic when it latches on
/obj/item/clothing/mask/facehugger/toy/examine()//So that giant red text about probisci doesn't show up.
if(desc)
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index a92a6019ec3..1b123084e63 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -19,13 +19,12 @@
/turf/simulated/mineral/ex_act(severity)
switch(severity)
if(3.0)
- return
+ if (prob(75))
+ src.gets_drilled()
if(2.0)
- if (prob(70))
- src.mineralAmt -= 1 //some of the stuff gets blown up
+ if (prob(90))
src.gets_drilled()
if(1.0)
- src.mineralAmt -= 2 //some of the stuff gets blown up
src.gets_drilled()
return
@@ -63,7 +62,7 @@
/turf/simulated/mineral/random
name = "Mineral deposit"
- var/mineralSpawnChanceList = list("Uranium" = 5, "Iron" = 50, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Plasma" = 25/*, "Adamantine" =5*/, "Cave" = 1)//Currently, Adamantine won't spawn as it has no uses. -Durandan
+ var/mineralSpawnChanceList = list("Uranium" = 5, "Iron" = 50, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Plasma" = 25, "Gibtonite" = 5/*, "Adamantine" =5*/, "Cave" = 1)//Currently, Adamantine won't spawn as it has no uses. -Durandan
var/mineralChance = 10 //means 10% chance of this plot changing to a mineral deposit
/turf/simulated/mineral/random/New()
@@ -88,7 +87,8 @@
M = new/turf/simulated/mineral/plasma(src)
if("Cave")
new/turf/simulated/floor/plating/asteroid/airless/cave(src)
-
+ if("Gibtonite")
+ M = new/turf/simulated/mineral/gibtonite(src)
/*if("Adamantine")
M = new/turf/simulated/mineral/adamantine(src)*/
if(M)
@@ -98,7 +98,7 @@
/turf/simulated/mineral/random/high_chance
mineralChance = 25
- mineralSpawnChanceList = list("Uranium" = 10, "Iron" = 30, "Diamond" = 2, "Gold" = 10, "Silver" = 10, "Plasma" = 25)
+ mineralSpawnChanceList = list("Uranium" = 10, "Iron" = 30, "Diamond" = 2, "Gold" = 10, "Silver" = 10, "Plasma" = 25, "Gibtonite" = 8)
/turf/simulated/mineral/uranium
name = "Uranium deposit"
@@ -163,6 +163,87 @@
spreadChance = 0
spread = 0
+////////////////////////////////Gibtonite
+/turf/simulated/mineral/gibtonite
+ name = "Diamond deposit" //honk
+ icon_state = "rock_Diamond"
+ mineralName = "Gibtonite"
+ mineralAmt = 1
+ spreadChance = 0
+ spread = 1
+ var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it
+ var/stage = 0 //How far into the lifecycle of gibtonite we are, 0 is untouched, 1 is active and attempting to detonate, 2 is benign and ready for extraction
+ var/activated_ckey = null //These are to track who triggered the gibtonite deposit for logging purposes
+ var/activated_name = null
+
+/turf/simulated/mineral/gibtonite/New()
+ det_time = rand(8,10) //So you don't know exactly when the hot potato will explode
+ ..()
+
+/turf/simulated/mineral/gibtonite/attackby(obj/item/I, mob/user)
+ if(istype(I, /obj/item/device/analyzer) && stage == 1)
+ user.visible_message("You use the analyzer to locate where to cut off the chain reaction and attempt to stop it...")
+ defuse()
+ if(istype(I, /obj/item/weapon/pickaxe))
+ src.activated_ckey = "[user.ckey]"
+ src.activated_name = "[user.name]"
+ ..()
+
+/turf/simulated/mineral/gibtonite/proc/explosive_reaction()
+ if(stage == 0)
+ icon_state = "rock_Gibtonite_active"
+ name = "Gibtonite deposit"
+ desc = "An active gibtonite reserve. Run!"
+ stage = 1
+ visible_message("There was gibtonite inside! It's going to explode!")
+ var/turf/bombturf = get_turf(src)
+ var/area/A = get_area(bombturf)
+ var/log_str = "[src.activated_ckey]? [src.activated_name] has triggered a gibtonite deposit reaction [A.name] (JMP)."
+ log_game(log_str)
+ countdown()
+
+/turf/simulated/mineral/gibtonite/proc/countdown()
+ spawn(0)
+ while(stage == 1 && det_time > 0 && mineralAmt >= 1)
+ det_time--
+ sleep(5)
+ if(stage == 1 && det_time <= 0 && mineralAmt >= 1)
+ var/turf/bombturf = get_turf(src)
+ mineralAmt = 0
+ explosion(bombturf,1,3,5, adminlog = 0)
+ if(stage == 0 || stage == 2)
+ return
+
+/turf/simulated/mineral/gibtonite/proc/defuse()
+ if(stage == 1)
+ icon_state = "rock_Gibtonite"
+ desc = "An inactive gibtonite reserve. The ore can be extracted."
+ stage = 2
+ if(det_time < 0)
+ det_time = 0
+ visible_message("The chain reaction was stopped! The gibtonite had [src.det_time] reactions left till the explosion!")
+
+/turf/simulated/mineral/gibtonite/gets_drilled()
+ if(stage == 0 && mineralAmt >= 1) //Gibtonite deposit is activated
+ playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,1)
+ explosive_reaction()
+ return
+ if(stage == 1 && mineralAmt >= 1) //Gibtonite deposit goes kaboom
+ var/turf/bombturf = get_turf(src)
+ mineralAmt = 0
+ explosion(bombturf,1,2,5, adminlog = 0)
+ if(stage == 2) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore.
+ var/obj/item/weapon/twohanded/required/gibtonite/G = new /obj/item/weapon/twohanded/required/gibtonite/(src)
+ if(det_time <= 0)
+ G.quality = 3
+ G.icon_state = "Gibtonite ore 3"
+ if(det_time >= 1 && det_time <= 2)
+ G.quality = 2
+ G.icon_state = "Gibtonite ore 2"
+ ..()
+
+////////////////////////////////End Gibtonite
+
/turf/simulated/floor/plating/asteroid/airless/cave
var/length = 100
@@ -256,6 +337,9 @@
user << "\blue You finish cutting into the rock."
gets_drilled()
+ if(istype(W, /obj/item/weapon/resonator))
+ var/obj/item/weapon/resonator/R = W
+ R.CreateResonance(src)
else
return attack_hand(user)
return
@@ -350,7 +434,7 @@
if(3.0)
return
if(2.0)
- if (prob(70))
+ if (prob(20))
src.gets_dug()
if(1.0)
src.gets_dug()
@@ -437,6 +521,9 @@
icon_state = "asteroid_dug"
return
+/turf/simulated/floor/plating/asteroid/proc/countdown()//This is here to stop runtimes in the event that changeturf() causes asteroid plating to take gibtonite procs
+ return
+
/turf/proc/updateMineralOverlays()
src.overlays.Cut()
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index 6da5e3e2451..31b8eaeff36 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -60,10 +60,51 @@
desc = "Completely useless"
icon_state = "slag"
+/obj/item/weapon/twohanded/required/gibtonite
+ name = "Gibtonite ore"
+ desc = "Extremely explosive if struck with mining equipment, Gibtonite is often used by miners to speed up their work by using it as a mining charge. This material is illegal to possess by unauthorized personnel under space law."
+ icon = 'icons/obj/mining.dmi'
+ icon_state = "Gibtonite ore"
+ item_state = "Gibtonite ore"
+ w_class = 4
+ throw_range = 0
+ anchored = 1 //Forces people to carry it by hand, no pulling!
+ var/primed = 0
+ var/det_time = 100
+ var/quality = 1 //How pure this gibtonite is, determines the explosion produced by it and is derived from the det_time of the rock wall it was taken from, higher value = better
+
+/obj/item/weapon/twohanded/required/gibtonite/attackby(obj/item/I, mob/user)
+ if(istype(I, /obj/item/weapon/pickaxe) && !primed)
+ playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,1)
+ primed = 1
+ icon_state = "Gibtonite active"
+ user.visible_message("[user] strikes the [src], causing a chain reaction!")
+ var/turf/bombturf = get_turf(src)
+ var/area/A = get_area(bombturf)
+ message_admins("[key_name(usr)]? has triggered a [name] to detonate at [A.name] (JMP).")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
+ spawn(det_time)
+ if(primed)
+ if(quality == 3)
+ explosion(src.loc,2,4,9)
+ if(quality == 2)
+ explosion(src.loc,1,2,5)
+ if(quality == 1)
+ explosion(src.loc,-1,1,3)
+ del(src)
+ if(istype(I, /obj/item/device/analyzer) && primed)
+ primed = 0
+ user.visible_message("The chain reaction was stopped! ...The ore's quality went down.")
+ icon_state = "Gibtonite ore"
+ quality = 1
+ ..()
+
/obj/item/weapon/ore/New()
pixel_x = rand(0,16)-8
pixel_y = rand(0,8)-8
+/obj/item/weapon/ore/ex_act()
+ return
/*****************************Coin********************************/
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 530fa9cb8d0..70e4eada2f7 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -161,12 +161,11 @@ Doesn't work on other aliens/AI.*/
set desc = "Empties the contents of your stomach"
set category = "Alien"
- if(powerc())
- if(stomach_contents.len)
- for(var/mob/M in src)
- if(M in stomach_contents)
- stomach_contents.Remove(M)
- M.loc = loc
- //Paralyse(10)
- src.visible_message("\green [src] hurls out the contents of their stomach!")
+ if(powerc() && stomach_contents.len)
+ for(var/atom/movable/A in stomach_contents)
+ if(A in stomach_contents)
+ stomach_contents.Remove(A)
+ A.loc = loc
+ //Paralyse(10)
+ src.visible_message("\green [src] hurls out the contents of their stomach!")
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index 7285b33e581..93d736cdaa7 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -392,6 +392,8 @@
sight &= ~SEE_OBJS
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ if(see_override)
+ see_invisible = see_override
if (healths)
if (stat != 2)
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index 3ab2a1a14dd..56e02fd1552 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -305,6 +305,8 @@
sight &= ~SEE_OBJS
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ if(see_override)
+ see_invisible = see_override
if (healths)
if (stat != 2)
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index c12e5b31611..861f63f0c10 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -100,6 +100,9 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
+ if(istype(new_xeno.loc,/mob/living/carbon))
+ var/mob/living/carbon/digester = new_xeno.loc
+ digester.stomach_contents += new_xeno
del(src)
/*----------------------------------------
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index f4fee6df253..6e546c5d4be 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -219,6 +219,8 @@
sight &= ~SEE_OBJS
see_in_dark = 2
see_invisible = SEE_INVISIBLE_LIVING
+ if(see_override)
+ see_invisible = see_override
if (healths)
if (stat != 2)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index b96a7e08eb1..5205d76765b 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -315,15 +315,16 @@
/mob/living/carbon/clean_blood()
- . = ..()
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.gloves)
if(H.gloves.clean_blood())
H.update_inv_gloves(0)
else
+ ..() // Clear the Blood_DNA list
if(H.bloody_hands)
H.bloody_hands = 0
+ H.bloody_hands_mob = null
H.update_inv_gloves(0)
update_icons() //apply the now updated overlays to the mob
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 4c79911d874..0f8a23af627 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -54,6 +54,11 @@
if(HULK in mutations) return
..()
+/mob/living/carbon/human/update_canmove()
+ var/old_lying = lying
+ . = ..()
+ if(lying && !old_lying && !resting && !buckled) // fell down
+ playsound(loc, "bodyfall", 50, 1, -1)
////////////////////////////////////////////
//Returns a list of damaged organs
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index d49e64f99b1..c951aaf0797 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -122,43 +122,6 @@ emp_act
var/obj/item/organ/limb/affecting = get_organ(ran_zone(user.zone_sel.selecting))
-//--------------------- Cyber limb stuff ---------------------\\
-
- if(istype(I, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = I
- if(affecting.status == ORGAN_ROBOTIC)
- if (WT.remove_fuel(0))
- if(affecting.brute_dam > 0)
- affecting.heal_damage(30,0,1) //Repair Brute
- update_damage_overlays(0)
- updatehealth()
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\blue [user] has fixed some of the dents on [src]'s [affecting.getDisplayName()]!"), 1) //Tell everyone [src]'s limb (by its real name) has been repaired
- return //So we don't attack them as well
- else
- user << "[src]'s [affecting.getDisplayName()] is already in good condition"
- return
- else
- user << "Need more welding fuel!"
- return
-
-
- if(istype(I, /obj/item/weapon/cable_coil))
- var/obj/item/weapon/cable_coil/coil = I
- if(affecting.status == ORGAN_ROBOTIC)
- if(affecting.burn_dam > 0)
- affecting.heal_damage(0,30,1) //Repair Burn
- updatehealth()
- coil.use(1)
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\blue [user] has fixed some of the burnt wires on [src]'s [affecting.getDisplayName()]!"), 1)
- return //So we don't attack them as well
- else
- user << "[src]'s [affecting.getDisplayName()] is already in good condition"
- return
-
-//-------------------- End of Cyber limb stuff ---------------------\\
-
var/hit_area = parse_zone(affecting.name)
if((user != src) && check_shields(I.force, "the [I.name]"))
@@ -199,12 +162,8 @@ emp_act
if (H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
G.add_blood(H)
- G.transfer_blood = 2
- G.bloody_hands_mob = H
else
H.add_blood(H)
- H.bloody_hands = 2
- H.bloody_hands_mob = H
H.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 81d47b51b94..79656573a95 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1018,6 +1018,8 @@
if(healths) healths.icon_state = "health7" //DEAD healthmeter
else
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
+ var/see_temp = see_invisible
+ see_invisible = SEE_INVISIBLE_LIVING
if(dna)
switch(dna.mutantrace)
if("lizard","slime")
@@ -1031,15 +1033,10 @@
if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
- if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(seer)
- var/obj/effect/rune/R = locate() in loc
- if(R && R.word1 == wordsee && R.word2 == wordhell && R.word3 == wordjoin)
- see_invisible = SEE_INVISIBLE_OBSERVER
- else
- see_invisible = SEE_INVISIBLE_LIVING
- seer = 0
+ see_invisible = SEE_INVISIBLE_OBSERVER
if(mind && mind.changeling)
hud_used.lingchemdisplay.invisibility = 0
@@ -1057,34 +1054,30 @@
target_list += target
if(target_list.len)//Everything else is handled by the ninja mask proc.
O.assess_targets(target_list, src)
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
+ see_invisible = SEE_INVISIBLE_LIVING
if(1)
see_in_dark = 5
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
+ see_invisible = SEE_INVISIBLE_LIVING
if(2)
sight |= SEE_MOBS
- if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(3)
sight |= SEE_TURFS
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
+ see_invisible = SEE_INVISIBLE_LIVING
if(glasses)
if(istype(glasses, /obj/item/clothing/glasses/meson))
sight |= SEE_TURFS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
+ see_invisible = SEE_INVISIBLE_MINIMUM
else if(istype(glasses, /obj/item/clothing/glasses/night))
see_in_dark = 5
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
+ see_invisible = SEE_INVISIBLE_MINIMUM
else if(istype(glasses, /obj/item/clothing/glasses/thermal))
sight |= SEE_MOBS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
+ see_invisible = SEE_INVISIBLE_MINIMUM
else if(istype(glasses, /obj/item/clothing/glasses/material))
sight |= SEE_OBJS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
+ see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
@@ -1094,17 +1087,20 @@
if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
if(O.hud) O.hud.process_hud(src)
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
+ see_invisible = SEE_INVISIBLE_LIVING
else if(istype(glasses, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/O = glasses
O.process_hud(src)
- if(!druggy)
- see_invisible = SEE_INVISIBLE_LIVING
+ see_invisible = SEE_INVISIBLE_LIVING
else
see_invisible = SEE_INVISIBLE_LIVING
- else
- see_invisible = SEE_INVISIBLE_LIVING
+
+ if(druggy) //Override for druggy
+ see_invisible = see_temp
+
+ if(see_override) //Override all
+ see_invisible = see_override
if(healths)
switch(hal_screwyhud)
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 57a78df5ecf..eba2999c738 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -482,6 +482,8 @@
sight &= ~SEE_OBJS
see_in_dark = 2
see_invisible = SEE_INVISIBLE_LIVING
+ if(see_override)
+ see_invisible = see_override
if (healths)
if (stat != 2)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 953384f9182..f241d3c7a54 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -259,6 +259,7 @@
setOxyLoss(0)
setCloneLoss(0)
setBrainLoss(0)
+ setHalLoss(0)
SetParalysis(0)
SetStunned(0)
SetWeakened(0)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 88167c46fb3..096e77023dd 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -24,23 +24,31 @@
return P.on_hit(src, armor, def_zone)
/mob/living/hitby(atom/movable/AM)//Standardization and logging -Sieve
- if(istype(AM, /obj/))
- var/obj/O = AM
+ if(istype(AM, /obj/item))
+ var/obj/item/I = AM
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
- if(istype(O,/obj/item/weapon))
- var/obj/item/weapon/W = O
+ if(istype(I,/obj/item/weapon))
+ var/obj/item/weapon/W = I
dtype = W.damtype
- visible_message("[src] has been hit by [O].", \
- "[src] has been hit by [O].")
+ if (W.throwhitsound && W.throwforce > 0)
+ playsound(loc, W.throwhitsound, 30, 1, -1)
+ else if(W.throwtapsound && W.throwforce == 0)
+ playsound(loc, W.throwtapsound, 30, 1, -1)
+ else if(W.hitsound && W.throwforce > 0)
+ playsound(loc, W.hitsound, 30, 1, -1)
+ else
+ playsound(loc, I.throwtapsound, 30, 1, -1)
+ visible_message("[src] has been hit by [I].", \
+ "[src] has been hit by [I].")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].")
- apply_damage(O.throwforce, dtype, zone, armor, O)
- if(!O.fingerprintslast)
+ apply_damage(I.throwforce, dtype, zone, armor, I)
+ if(!I.fingerprintslast)
return
- var/client/assailant = directory[ckey(O.fingerprintslast)]
+ var/client/assailant = directory[ckey(I.fingerprintslast)]
if(assailant && assailant.mob && istype(assailant.mob,/mob))
var/mob/M = assailant.mob
- add_logs(M, src, "hit", object="[O]")
+ add_logs(M, src, "hit", object="[I]")
//Mobs on Fire
/mob/living/proc/IgniteMob()
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 028a233013c..f9f5c89b9da 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -58,6 +58,8 @@
src.sight |= SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ if(see_override)
+ see_invisible = see_override
var/area/home = get_area(src)
if(!home) return//something to do with malf fucking things up I guess. <-- aisat is gone. is this still necessary? ~Carn
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index a27b540b3d5..1860e7ab640 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -145,25 +145,25 @@
src.sight |= SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
- else if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
- src.sight |= SEE_TURFS
- src.sight |= SEE_MOBS
+ else
src.see_in_dark = 8
- see_invisible = SEE_INVISIBLE_MINIMUM
- else if (src.sight_mode & BORGMESON)
- src.sight |= SEE_TURFS
- src.see_in_dark = 8
- see_invisible = SEE_INVISIBLE_MINIMUM
- else if (src.sight_mode & BORGTHERM)
- src.sight |= SEE_MOBS
- src.see_in_dark = 8
- 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_in_dark = 8
- src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ 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
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ 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
+ if(see_override)
+ see_invisible = see_override
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 93cfbefb5b6..010c6361fa1 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -389,9 +389,9 @@
var/obj/item/weapon/cable_coil/coil = W
adjustFireLoss(-30)
updatehealth()
- coil.use(1)
for(var/mob/O in viewers(user, null))
O.show_message(text("\red [user] has fixed some of the burnt wires on [src]!"), 1)
+ coil.use(1)
else if (istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover
if(opened)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 47078644b3a..0e7499372b3 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -139,7 +139,7 @@
melee_damage_upper = 30
attacktext = "smashes their armoured gauntlet into"
speed = 3
- wall_smash = 1
+ environment_smash = 2
attack_sound = 'sound/weapons/punch3.ogg'
status_flags = 0
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
@@ -235,7 +235,7 @@
melee_damage_upper = 5
attacktext = "rams"
speed = 0
- wall_smash = 1
+ environment_smash = 2
attack_sound = 'sound/weapons/punch2.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
@@ -263,7 +263,7 @@
melee_damage_upper = 50
attacktext = "brutally crushes"
speed = 5
- wall_smash = 1
+ environment_smash = 2
attack_sound = 'sound/weapons/punch4.ogg'
var/energy = 0
var/max_energy = 1000
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 8c139777168..95cee265f23 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -29,7 +29,6 @@
max_n2 = 0
unsuitable_atoms_damage = 15
faction = "alien"
- wall_smash = 1
status_flags = CANPUSH
minbodytemp = 0
heat_damage_per_tick = 20
@@ -52,6 +51,8 @@
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
+ retreat_distance = 5
+ minimum_distance = 5
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
@@ -66,6 +67,8 @@
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
+ retreat_distance = 5
+ minimum_distance = 5
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index d2601c3303d..33425228628 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -50,4 +50,12 @@
if(istype(L))
if(prob(15))
L.Weaken(3)
- L.visible_message("\the [src] knocks down \the [L]!")
\ No newline at end of file
+ L.visible_message("\the [src] knocks down \the [L]!")
+
+/mob/living/simple_animal/hostile/carp/holocarp
+ icon_state = "holocarp"
+ icon_living = "holocarp"
+
+/mob/living/simple_animal/hostile/carp/holocarp/Die()
+ del(src)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index c8a74487949..d2f7e80559a 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -31,10 +31,14 @@
name = "hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
+ retreat_distance = 5
+ minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
+ retreat_distance = 5
+ minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/strong
name = "strong hivebot"
@@ -42,7 +46,6 @@
health = 80
ranged = 1
-
/mob/living/simple_animal/hostile/hivebot/Die()
..()
visible_message("[src] blows apart!")
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index a91d432033e..09a9ee16525 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -1,8 +1,11 @@
/mob/living/simple_animal/hostile
faction = "hostile"
+ mouse_opacity = 2 //This makes it easier to hit hostile mobs, you only need to click on their tile, and is set back to 1 when they die
+ stop_automated_movement_when_pulled = 0
+ environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
var/atom/target
- var/attack_same = 0
+ var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
var/ranged = 0
var/rapid = 0
var/projectiletype
@@ -10,72 +13,170 @@
var/casingtype
var/move_to_delay = 2 //delay for the automated movement.
var/list/friends = list()
- var/vision_range = 10
- var/idle_env_destroyer = 0
- stop_automated_movement_when_pulled = 0
+ var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view
-/mob/living/simple_animal/hostile/proc/FindTarget()
+ var/aggro_vision_range = 9 //If a mob is aggro, we search in this radius. Defaults to 9 to keep in line with original simple mob aggro radius
+ var/idle_vision_range = 9 //If a mob is just idling around, it's vision range is limited to this. Defaults to 9 to keep in line with original simple mob aggro radius
+ var/ranged_message = "fires" //Fluff text for ranged mobs
+ var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks
+ var/ranged_cooldown_cap = 3 //What ranged attacks, after being used are set to, to go back on cooldown, defaults to 3 life() ticks
+ var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
+ var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
+ var/search_objects = 0 //If we want to consider objects when searching around, set this to 1. If you want to search for objects while also ignoring mobs until hurt, set it to 2. To completely ignore mobs, even when attacked, set it to 3
+ var/list/wanted_objects = list() //A list of objects that will be checked against to attack, should we have search_objects enabled
+ var/stat_attack = 0 //Mobs with stat_attack to 1 will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
+ var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
+ var/attack_faction = null //Put a faction string here to have a mob only ever attack a specific faction
- var/atom/T = null
- stop_automated_movement = 0
- for(var/atom/A in ListTargets())
+/mob/living/simple_animal/hostile/Life()
- var/atom/F = Found(A)
- if(F)
- T = F
- break
-
- if(!CanAttack(A))
- continue
-
- if(isliving(A))
- T = A
- break
-
- else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets().
- var/obj/mecha/M = A
- if (M.occupant)
- T = M
- break
-
- return T
-
-/mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)
- if(!..())
+ . = ..()
+ if(!.)
+ walk(src, 0)
return 0
- if(isliving(the_target))
- var/mob/living/L = the_target
- if(L.faction == src.faction && !attack_same)
- return 0
- else if(L in friends)
- return 0
- return 1
+ if(client)
+ return 0
+ if(!stat)
+ switch(stance)
+ if(HOSTILE_STANCE_IDLE)
+ if(environment_smash)
+ EscapeConfinement()
+ var/new_target = FindTarget()
+ GiveTarget(new_target)
-/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)
+ if(HOSTILE_STANCE_ATTACK)
+ MoveToTarget()
+ DestroySurroundings()
+
+ if(HOSTILE_STANCE_ATTACKING)
+ AttackTarget()
+ DestroySurroundings()
+
+ if(ranged)
+ ranged_cooldown--
+
+//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
+
+
+/mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see
+ var/list/L = list()
+ if(!search_objects)
+ var/list/Mobs = hearers(vision_range, src) - src //Remove self, so we don't suicide
+ L += Mobs
+ for(var/obj/mecha/M in mechas_list)
+ if(get_dist(M, src) <= vision_range && can_see(src, M, vision_range))
+ L += M
+ else
+ var/list/Objects = oview(vision_range, src)
+ L += Objects
+ return L
+
+/mob/living/simple_animal/hostile/proc/FindTarget()//Step 2, filter down possible targets to things we actually care about
+ var/list/Targets = list()
+ var/Target
+ for(var/atom/A in ListTargets())
+ if(Found(A))//Just in case people want to override targetting
+ var/list/FoundTarget = list()
+ FoundTarget += A
+ Targets = FoundTarget
+ break
+ if(CanAttack(A))//Can we attack it?
+ Targets += A
+ continue
+ Target = PickTarget(Targets)
+ return Target //We now have a target
+
+/mob/living/simple_animal/hostile/proc/Found(var/atom/A)//This is here as a potential override to pick a specific target if available
+ return
+
+/mob/living/simple_animal/hostile/proc/PickTarget(var/list/Targets)//Step 3, pick amongst the possible, attackable targets
+ if(target != null)//If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets
+ for(var/atom/A in Targets)
+ var/target_dist = get_dist(src, target)
+ var/possible_target_distance = get_dist(src, A)
+ if(target_dist < possible_target_distance)
+ Targets -= A
+ if(!Targets.len)//We didnt find nothin!
+ return
+ var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random
+ return chosen_target
+
+/mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)//Can we actually attack a possible target?
+ if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
+ return 0
+ if(isliving(the_target) && search_objects < 2)
+ var/mob/living/L = the_target
+ if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1)
+ return 0
+ if(L.faction == src.faction && !attack_same || L.faction != src.faction && attack_same == 2 || L.faction != attack_faction && attack_faction)
+ return 0
+ if(L in friends)
+ return 0
+ return 1
+ if(isobj(the_target))
+ if(the_target.type in wanted_objects)
+ return 1
+ if(istype(the_target, /obj/mecha) && search_objects < 2)
+ var/obj/mecha/M = the_target
+ if(M.occupant)//Just so we don't attack empty mechs
+ return 1
+ return 0
+
+/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target
target = new_target
if(target != null)
+ Aggro()
stance = HOSTILE_STANCE_ATTACK
return
-/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay)
- walk_to(src, target, 1, delay)
-
-/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
- return
-
-/mob/living/simple_animal/hostile/proc/MoveToTarget()
+/mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target
stop_automated_movement = 1
if(!target || !CanAttack(target))
LoseTarget()
+ return
if(target in ListTargets())
- if(ranged)
- if(get_dist(src, target) <= 6)
+ var/target_distance = get_dist(src,target)
+ if(ranged)//We ranged? Shoot at em
+ if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
OpenFire(target)
+ if(retreat_distance != null)//If we have a retreat distance, check if we need to run from our target
+ if(target_distance <= retreat_distance)//If target's closer than our retreat distance, run
+ walk_away(src,target,retreat_distance,move_to_delay)
else
- Goto(target, move_to_delay)
+ Goto(target,move_to_delay,minimum_distance)//Otherwise, get to our minimum distance so we chase them
else
- stance = HOSTILE_STANCE_ATTACKING
- Goto(target, move_to_delay)
+ Goto(target,move_to_delay,minimum_distance)
+ if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
+ AttackingTarget()
+ return
+ if(target.loc != null && get_dist(src, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still
+ if(FindHidden(target) && environment_smash)//Check if he tried to hide in something to lose us
+ var/atom/A = target.loc
+ Goto(A,move_to_delay,minimum_distance)
+ if(A.Adjacent(src))
+ A.attack_animal(src)
+ return
+ else
+ LostTarget()
+ LostTarget()
+
+/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance)
+ walk_to(src, target, minimum_distance, delay)
+
+/mob/living/simple_animal/hostile/adjustBruteLoss(var/damage)
+ ..(damage)
+ if(!stat && search_objects < 3)//Not unconscious, and we don't ignore mobs
+ if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
+ search_objects = 0
+ target = null
+ if(stance == HOSTILE_STANCE_IDLE)//If we took damage while idle, immediately attempt to find the source of it so we find a living target
+ Aggro()
+ var/new_target = FindTarget()
+ GiveTarget(new_target)
+ if(stance == HOSTILE_STANCE_ATTACK)//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
+ if(target != null && prob(25))
+ var/new_target = FindTarget()
+ GiveTarget(new_target)
/mob/living/simple_animal/hostile/proc/AttackTarget()
@@ -86,76 +187,43 @@
if(!(target in ListTargets()))
LostTarget()
return 0
- if(isturf(loc) && target.Adjacent(src)) //Attacking
+ if(isturf(loc) && target.Adjacent(src))
AttackingTarget()
return 1
/mob/living/simple_animal/hostile/proc/AttackingTarget()
- if(isliving(target))
- var/mob/living/L = target
- L.attack_animal(src)
- return L
- if(istype(target,/obj/mecha))
- var/obj/mecha/M = target
- M.attack_animal(src)
- return M
+ target.attack_animal(src)
+
+/mob/living/simple_animal/hostile/proc/Aggro()
+ vision_range = aggro_vision_range
+
+/mob/living/simple_animal/hostile/proc/LoseAggro()
+ stop_automated_movement = 0
+ vision_range = idle_vision_range
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE
target = null
walk(src, 0)
+ LoseAggro()
/mob/living/simple_animal/hostile/proc/LostTarget()
stance = HOSTILE_STANCE_IDLE
walk(src, 0)
+ LoseAggro()
-
-/mob/living/simple_animal/hostile/proc/ListTargets(var/override = -1)
-
- // Allows you to override how much the mob can see. Defaults to vision_range if none is entered.
- if(override == -1)
- override = vision_range
-
- var/list/L = hearers(src, override)
- for(var/obj/mecha/M in mechas_list)
- // Will check the distance before checking the line of sight, if the distance is small enough.
- if(get_dist(M, src) <= override && can_see(src, M, override))
- L += M
- return L
+//////////////END HOSTILE MOB TARGETTING AND AGGRESSION////////////
/mob/living/simple_animal/hostile/Die()
+ LoseAggro()
+ mouse_opacity = 1
..()
walk(src, 0)
-/mob/living/simple_animal/hostile/Life()
-
- . = ..()
- if(!.)
- walk(src, 0)
- return 0
- if(client)
- return 0
-
- if(!stat)
- switch(stance)
- if(HOSTILE_STANCE_IDLE)
- var/new_target = FindTarget()
- GiveTarget(new_target)
- if(idle_env_destroyer)
- DestroySurroundings()
-
- if(HOSTILE_STANCE_ATTACK)
- DestroySurroundings()
- MoveToTarget()
-
- if(HOSTILE_STANCE_ATTACKING)
- DestroySurroundings()
- AttackTarget()
-
/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
var/target = the_target
- visible_message("\red [src] fires at [target]!", 1)
+ visible_message("\red [src] [ranged_message] at [target]!", 1)
var/tturf = get_turf(target)
if(rapid)
@@ -175,11 +243,9 @@
Shoot(tturf, src.loc, src)
if(casingtype)
new casingtype
-
- LoseTarget()
+ ranged_cooldown = ranged_cooldown_cap
return
-
/mob/living/simple_animal/hostile/proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
if(target == start)
return
@@ -199,9 +265,27 @@
return
/mob/living/simple_animal/hostile/proc/DestroySurroundings()
- for(var/dir in cardinal) // North, South, East, West
- for(var/obj/structure/obstacle in get_step(src, dir))
- if(!obstacle.Adjacent(src))
- continue
- if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
- obstacle.attack_animal(src)
+ if(environment_smash)
+ EscapeConfinement()
+ for(var/dir in cardinal)
+ var/turf/T = get_step(src, dir)
+ if(istype(T, /turf/simulated/wall))
+ T.attack_animal(src)
+ for(var/atom/A in T)
+ if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/rack))
+ A.attack_animal(src)
+ return
+
+/mob/living/simple_animal/hostile/proc/EscapeConfinement()
+ if(buckled)
+ buckled.attack_animal(src)
+ if(!isturf(src.loc) && src.loc != null)//Did someone put us in something?
+ var/atom/A = src.loc
+ A.attack_animal(src)//Bang on it till we get out
+ return
+
+/mob/living/simple_animal/hostile/proc/FindHidden(var/atom/hidden_target)
+ if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper))
+ return 1
+ else
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
new file mode 100644
index 00000000000..e7a37bb85cf
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
@@ -0,0 +1,310 @@
+/mob/living/simple_animal/hostile/asteroid/
+ vision_range = 2
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ unsuitable_atoms_damage = 15
+ faction = "mining"
+ environment_smash = 2
+ minbodytemp = 0
+ heat_damage_per_tick = 20
+ response_help = "pokes"
+ response_disarm = "shoves"
+ response_harm = "strikes"
+ status_flags = 0
+ a_intent = "harm"
+ var/throw_message = "bounces off of"
+ var/icon_aggro = null // for swapping to when we get aggressive
+
+/mob/living/simple_animal/hostile/asteroid/Aggro()
+ ..()
+ icon_state = icon_aggro
+
+/mob/living/simple_animal/hostile/asteroid/LoseAggro()
+ ..()
+ icon_state = icon_living
+
+/mob/living/simple_animal/hostile/asteroid/bullet_act(var/obj/item/projectile/P)//Limits the weapons available to kill them at range
+ if(!stat)
+ Aggro()
+ if(P.damage < 30)
+ visible_message("The [P.name] had no effect on [src.name]!")
+ return
+ ..()
+
+/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)//No floor tiling them to death, wiseguy
+ if(istype(AM, /obj/item))
+ var/obj/item/T = AM
+ if(!stat)
+ Aggro()
+ if(T.throwforce <= 15)
+ visible_message("The [T.name] [src.throw_message] [src.name]!")
+ return
+ ..()
+
+/mob/living/simple_animal/hostile/asteroid/basilisk
+ name = "basilisk"
+ desc = "A territorial beast, covered in a thick shell that absorbs energy. Its stare causes victims to freeze from the inside."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Basilisk"
+ icon_living = "Basilisk"
+ icon_aggro = "Basilisk_alert"
+ icon_dead = "Basilisk_dead"
+ icon_gib = "syndicate_gib"
+ move_to_delay = 20
+ projectiletype = /obj/item/projectile/temp/basilisk
+ projectilesound = 'sound/weapons/pierce.ogg'
+ ranged = 1
+ ranged_message = "stares"
+ ranged_cooldown_cap = 8
+ throw_message = "does nothing against the hard shell of"
+ vision_range = 2
+ speed = 3
+ maxHealth = 200
+ health = 200
+ harm_intent_damage = 5
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attacktext = "bites into"
+ a_intent = "harm"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ ranged_cooldown_cap = 4
+ aggro_vision_range = 9
+ idle_vision_range = 2
+
+/obj/item/projectile/temp/basilisk
+ name = "freezing blast"
+ icon_state = "ice_2"
+ damage = 0
+ damage_type = BURN
+ nodamage = 1
+ flag = "energy"
+ temperature = 50
+
+/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(var/new_target)
+ target = new_target
+ if(target != null)
+ Aggro()
+ stance = HOSTILE_STANCE_ATTACK
+ if(isliving(target))
+ var/mob/living/L = target
+ if(L.bodytemperature > 261)
+ L.bodytemperature = 261
+ visible_message("The [src.name]'s stare chills [L.name] to the bone!")
+ return
+
+/mob/living/simple_animal/hostile/asteroid/goldgrub
+ name = "goldgrub"
+ desc = "A worm that grows fat from eating everything in its sight. Seems to enjoy precious metals and other shiny things, hence the name."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Goldgrub"
+ icon_living = "Goldgrub"
+ icon_aggro = "Goldgrub_alert"
+ icon_dead = "Goldgrub_dead"
+ icon_gib = "syndicate_gib"
+ vision_range = 6
+ aggro_vision_range = 9
+ idle_vision_range = 6
+ move_to_delay = 3
+ friendly = "harmlessly rolls into"
+ maxHealth = 45
+ health = 45
+ harm_intent_damage = 5
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ attacktext = "barrels into"
+ a_intent = "help"
+ throw_message = "sinks in slowly, before being pushed out of "
+ status_flags = CANPUSH
+ search_objects = 2
+ wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, /obj/item/weapon/ore/plasma,
+ /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/iron, /obj/item/weapon/ore/clown)
+ var/alerted = 0
+
+/mob/living/simple_animal/hostile/asteroid/goldgrub/GiveTarget(var/new_target)
+ target = new_target
+ if(target != null)
+ if(istype(target, /obj/item/weapon/ore))
+ visible_message("The [src.name] looks at [target.name] with hungry eyes.")
+ stance = HOSTILE_STANCE_ATTACK
+ if(isliving(target) && !search_objects)
+ Aggro()
+ stance = HOSTILE_STANCE_ATTACK
+ visible_message("The [src.name] tries to flee from [target.name]!")
+ retreat_distance = 10
+ Burrow()
+ return
+
+/obj/item/weapon/ore/attack_animal(var/mob/living/L)
+ if(istype(L, /mob/living/simple_animal/hostile/asteroid/goldgrub))
+ L.visible_message("The [src.name] was swallowed whole!")
+ del(src)
+ ..()
+
+/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time
+ if(!alerted)
+ alerted = 1
+ spawn(100)
+ if(alerted)
+ visible_message("The [src.name] buries into the ground, vanishing from sight!")
+ del(src)
+
+/mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(var/obj/item/projectile/P)
+ visible_message("The [P.name] was repelled by [src.name]'s girth!")
+ return
+
+/mob/living/simple_animal/hostile/asteroid/goldgrub/Die()
+ alerted = 0
+ ..()
+
+/mob/living/simple_animal/hostile/asteroid/hivelord
+ name = "hivelord"
+ desc = "A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Hivelord"
+ icon_living = "Hivelord"
+ icon_aggro = "Hivelord_alert"
+ icon_dead = "Hivelord_dead"
+ icon_gib = "syndicate_gib"
+ mouse_opacity = 2
+ move_to_delay = 12
+ ranged = 1
+ vision_range = 5
+ aggro_vision_range = 9
+ idle_vision_range = 5
+ speed = 3
+ maxHealth = 75
+ health = 75
+ harm_intent_damage = 5
+ melee_damage_lower = 2
+ melee_damage_upper = 2
+ attacktext = "lashes out at"
+ throw_message = "falls right through the strange body of the"
+ ranged_cooldown = 0
+ ranged_cooldown_cap = 0
+ environment_smash = 0
+ retreat_distance = 5
+ minimum_distance = 5
+ pass_flags = PASSTABLE
+
+/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(var/the_target)
+ var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood(src.loc)
+ A.GiveTarget(target)
+ return
+
+/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
+ OpenFire()
+ ..()
+
+/mob/living/simple_animal/hostile/asteroid/hivelordbrood
+ name = "hivelord brood"
+ desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Hivelordbrood"
+ icon_living = "Hivelordbrood"
+ icon_aggro = "Hivelordbrood"
+ icon_dead = "Hivelordbrood"
+ icon_gib = "syndicate_gib"
+ mouse_opacity = 2
+ move_to_delay = 0
+ friendly = "buzzes near"
+ vision_range = 10
+ speed = 3
+ maxHealth = 1
+ health = 1
+ harm_intent_damage = 5
+ melee_damage_lower = 2
+ melee_damage_upper = 2
+ attacktext = "slashes"
+ throw_message = "falls right through the strange body of the"
+ environment_smash = 0
+ pass_flags = PASSTABLE
+
+/mob/living/simple_animal/hostile/asteroid/hivelordbrood/New()
+ ..()
+ spawn(100)
+ del(src)
+
+/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Die()
+ del(src)
+
+/mob/living/simple_animal/hostile/asteroid/goliath
+ name = "goliath"
+ desc = "A massive beast that uses long tentacles to ensare its prey, threatening them is not advised under any conditions."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Goliath"
+ icon_living = "Goliath"
+ icon_aggro = "Goliath_alert"
+ icon_dead = "Goliath_dead"
+ icon_gib = "syndicate_gib"
+ attack_sound = 'sound/weapons/punch4.ogg'
+ mouse_opacity = 2
+ move_to_delay = 40
+ ranged = 1
+ ranged_cooldown_cap = 8
+ friendly = "wails at"
+ vision_range = 5
+ speed = 3
+ maxHealth = 300
+ health = 300
+ harm_intent_damage = 0
+ melee_damage_lower = 25
+ melee_damage_upper = 25
+ attacktext = "pulverizes"
+ throw_message = "does nothing to the rocky hide of the"
+ aggro_vision_range = 9
+ idle_vision_range = 5
+
+/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire()
+ visible_message("The [src.name] digs its tentacles under [target.name]!")
+ var/tturf = get_turf(target)
+ new /obj/effect/goliath_tentacle/original(tturf)
+ ranged_cooldown = ranged_cooldown_cap
+ return
+
+/mob/living/simple_animal/hostile/asteroid/goliath/adjustBruteLoss(var/damage)
+ ranged_cooldown--
+ ..()
+
+/obj/effect/goliath_tentacle/
+ name = "Goliath tentacle"
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "Goliath_tentacle"
+
+/obj/effect/goliath_tentacle/New()
+ var/turftype = get_turf(src)
+ if(istype(turftype, /turf/simulated/mineral))
+ var/turf/simulated/mineral/M = turftype
+ M.gets_drilled()
+ spawn(20)
+ Trip()
+
+/obj/effect/goliath_tentacle/original
+
+/obj/effect/goliath_tentacle/original/New()
+ var/list/directions = cardinal.Copy()
+ var/counter
+ for(counter = 1, counter <= 3, counter++)
+ var/spawndir = pick(directions)
+ directions -= spawndir
+ var/turf/T = get_step(src,spawndir)
+ new /obj/effect/goliath_tentacle(T)
+ ..()
+
+/obj/effect/goliath_tentacle/proc/Trip()
+ for(var/mob/living/M in src.loc)
+ M.Weaken(5)
+ visible_message("The [src.name] knocks [M.name] down!")
+ del(src)
+
+/obj/effect/goliath_tentacle/Crossed(AM as mob|obj)
+ if(isliving(AM))
+ Trip()
+ return
+ ..()
+
diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm
index 913693cd899..691490c61c8 100644
--- a/code/modules/mob/living/simple_animal/hostile/pirate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm
@@ -33,7 +33,6 @@
var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate
faction = "pirate"
- idle_env_destroyer = 0
/mob/living/simple_animal/hostile/pirate/ranged
name = "Pirate Gunner"
@@ -43,6 +42,8 @@
projectilesound = 'sound/weapons/laser.ogg'
ranged = 1
rapid = 1
+ retreat_distance = 5
+ minimum_distance = 5
projectiletype = /obj/item/projectile/beam
corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
weapon1 = /obj/item/weapon/gun/energy/laser
diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm
index dabc37dcf77..8e5c5c70a8b 100644
--- a/code/modules/mob/living/simple_animal/hostile/russian.dm
+++ b/code/modules/mob/living/simple_animal/hostile/russian.dm
@@ -32,7 +32,6 @@
unsuitable_atoms_damage = 15
faction = "russian"
status_flags = CANPUSH
- idle_env_destroyer = 0
/mob/living/simple_animal/hostile/russian/ranged
@@ -41,6 +40,8 @@
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba
ranged = 1
+ retreat_distance = 5
+ minimum_distance = 5
projectiletype = /obj/item/projectile/bullet
projectilesound = 'sound/weapons/Gunshot.ogg'
casingtype = /obj/item/ammo_casing/a357
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index bee74b1dd7d..4896ea69979 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -31,10 +31,8 @@
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
- wall_smash = 1
faction = "syndicate"
status_flags = CANPUSH
- idle_env_destroyer = 0
/mob/living/simple_animal/hostile/syndicate/Die()
..()
@@ -105,6 +103,8 @@
/mob/living/simple_animal/hostile/syndicate/ranged
ranged = 1
rapid = 1
+ retreat_distance = 5
+ minimum_distance = 5
icon_state = "syndicateranged"
icon_living = "syndicateranged"
casingtype = /obj/item/ammo_casing/a12mm
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 295a86a67c4..45353303b5f 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -53,7 +53,7 @@
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles" //If the mob does no damage with it's attack
- var/wall_smash = 0 //if they can smash walls
+ var/environment_smash = 0 //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 4902ca14738..992363d7da9 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -94,6 +94,7 @@
var/obj/item/weapon/storage/s_active = null//Carbon
var/seer = 0 //for cult//Carbon, probably Human
+ var/see_override = 0 //0 for no override, sets see_invisible = see_override in mob life process
var/datum/hud/hud_used = null
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index fb7912e7c61..7aedac1d3be 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -220,6 +220,19 @@
return(OXYLOSS)
+/obj/item/weapon/cable_coil/attack(mob/living/carbon/human/H, mob/user)
+ var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
+ if(istype(H))
+ if(affecting.status == ORGAN_ROBOTIC)
+ src.item_heal_robotic(H, user, 0, 30)
+ src.use(1)
+ return
+ else
+ return ..()
+ else
+ return ..()
+
+
/obj/item/weapon/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
..()
src.amount = length
diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm
index b6557e600d0..819c228617b 100644
--- a/code/modules/projectiles/ammunition/energy.dm
+++ b/code/modules/projectiles/ammunition/energy.dm
@@ -103,4 +103,10 @@
/obj/item/ammo_casing/energy/meteor
projectile_type = /obj/item/projectile/meteor
- select_name = "goddamn meteor"
\ No newline at end of file
+ select_name = "goddamn meteor"
+
+/obj/item/ammo_casing/energy/kinetic
+ projectile_type = /obj/item/projectile/kinetic
+ select_name = "kinetic"
+ e_cost = 500
+ fire_sound = 'sound/weapons/Gunshot4.ogg'
diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm
index 590e9c5177e..c4e70ca153c 100644
--- a/code/modules/projectiles/firing.dm
+++ b/code/modules/projectiles/firing.dm
@@ -21,6 +21,10 @@
BB.firer = user
BB.def_zone = user.zone_sel.selecting
BB.silenced = quiet
+
+ if(reagents && BB.reagents)
+ reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets
+ reagents.delete()
return
/obj/item/ammo_casing/proc/throw_proj(var/turf/targloc, mob/living/user as mob|obj, params)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 241a7145478..eaef43c40c3 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -102,4 +102,30 @@
name = "mind flayer"
desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon."
icon_state = "xray"
- ammo_type = list(/obj/item/ammo_casing/energy/mindflayer)
+ ammo_type = list(/obj/item/ammo_casing/energy/mindflayer)
+
+/obj/item/weapon/gun/energy/kinetic_accelerator
+ name = "proto-kinetic accelerator"
+ desc = "According to Nanotrasen accounting, this is mining equipment. It's been modified for extreme power output to crush rocks, but often serves as a miner's first defense against hostile alien life; it's not very powerful unless used in a low pressure environment."
+ icon_state = "kineticgun"
+ item_state = "kineticgun"
+ ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
+ cell_type = "/obj/item/weapon/cell/crap"
+ var/overheat = 0
+ var/recent_reload = 1
+
+/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot()
+ overheat = 1
+ spawn(20)
+ overheat = 0
+ recent_reload = 0
+ ..()
+
+/obj/item/weapon/gun/energy/kinetic_accelerator/attack_self(var/mob/living/user/L)
+ if(overheat || recent_reload)
+ return
+ power_supply.give(500)
+ playsound(src.loc, 'sound/weapons/shotgunpump.ogg', 60, 1)
+ recent_reload = 1
+ update_icon()
+ return
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index 875bd2622f3..5edc83056b7 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -36,11 +36,6 @@
else if (magazine.ammo_count())
chambered = magazine.get_round()
chambered.loc = src
- if(chambered.BB)
- if(chambered.reagents && chambered.BB.reagents)
- var/datum/reagents/casting_reagents = chambered.reagents
- casting_reagents.trans_to(chambered.BB, casting_reagents.total_volume) //For chemical darts/bullets
- casting_reagents.delete()
return
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 9e483255dd7..fde3978b1a3 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -141,4 +141,8 @@
if(!(original in permutated))
Bump(original)
sleep(1)
+ Range()
return
+
+/obj/item/projectile/proc/Range()
+ return
diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm
deleted file mode 100644
index 94c48a1273c..00000000000
--- a/code/modules/projectiles/projectile/animate.dm
+++ /dev/null
@@ -1,17 +0,0 @@
-/obj/item/projectile/animate
- name = "bolt of animation"
- icon_state = "red_1"
- damage = 0
- damage_type = BURN
- nodamage = 1
- flag = "energy"
-
-/obj/item/projectile/animate/Bump(var/atom/change)
- . = ..()
- if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects))
- var/obj/O = change
- new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer)
- else if(istype(change, /mob/living/simple_animal/hostile/mimic/copy))
- // Change our allegiance!
- var/mob/living/simple_animal/hostile/mimic/copy/C = change
- C.ChangeOwner(firer)
diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm
deleted file mode 100644
index 34c03d25919..00000000000
--- a/code/modules/projectiles/projectile/change.dm
+++ /dev/null
@@ -1,112 +0,0 @@
-/obj/item/projectile/change
- name = "bolt of change"
- icon_state = "ice_1"
- damage = 0
- damage_type = BURN
- nodamage = 1
- flag = "energy"
-
- on_hit(var/atom/change)
- wabbajack(change)
-
-
-/obj/item/projectile/change/proc/wabbajack (mob/M as mob in living_mob_list)
- if(istype(M, /mob/living) && M.stat != DEAD)
- if(M.notransform) return
- M.notransform = 1
- M.canmove = 0
- M.icon = null
- M.overlays.Cut()
- M.invisibility = 101
-
- if(istype(M, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/Robot = M
- if(Robot.mmi) del(Robot.mmi)
- else
- for(var/obj/item/W in M)
- if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
- del(W)
- continue
- W.layer = initial(W.layer)
- W.loc = M.loc
- W.dropped(M)
-
- var/mob/living/new_mob
-
- var/randomize = pick("monkey","robot","slime","xeno","human","animal")
- switch(randomize)
- if("monkey")
- new_mob = new /mob/living/carbon/monkey(M.loc)
- new_mob.universal_speak = 1
- if("robot")
- new_mob = new /mob/living/silicon/robot(M.loc)
- new_mob.gender = M.gender
- new_mob.invisibility = 0
- new_mob.job = "Cyborg"
- var/mob/living/silicon/robot/Robot = new_mob
- Robot.mmi = new /obj/item/device/mmi(new_mob)
- Robot.mmi.transfer_identity(M) //Does not transfer key/client.
- if("slime")
- if(prob(50)) new_mob = new /mob/living/carbon/slime/adult(M.loc)
- else new_mob = new /mob/living/carbon/slime(M.loc)
- new_mob.universal_speak = 1
- if("xeno")
- if(prob(50))
- new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
- else
- new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
- new_mob.universal_speak = 1
-
- /*var/alien_caste = pick("Hunter","Sentinel","Drone","Larva")
- switch(alien_caste)
- if("Hunter") new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
- if("Sentinel") new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
- if("Drone") new_mob = new /mob/living/carbon/alien/humanoid/drone(M.loc)
- else new_mob = new /mob/living/carbon/alien/larva(M.loc)
- new_mob.universal_speak = 1*/
- if("animal")
- var/animal = pick("parrot","corgi","crab","pug","cat","carp","bear","mushroom","tomato","mouse","chicken","cow","lizard","chick")
- switch(animal)
- if("parrot") new_mob = new /mob/living/simple_animal/parrot(M.loc)
- if("corgi") new_mob = new /mob/living/simple_animal/corgi(M.loc)
- if("crab") new_mob = new /mob/living/simple_animal/crab(M.loc)
- if("pug") new_mob = new /mob/living/simple_animal/pug(M.loc)
- if("cat") new_mob = new /mob/living/simple_animal/cat(M.loc)
- if("carp") new_mob = new /mob/living/simple_animal/hostile/carp(M.loc)
- if("bear") new_mob = new /mob/living/simple_animal/hostile/bear(M.loc)
- if("mushroom") new_mob = new /mob/living/simple_animal/mushroom(M.loc)
- if("tomato") new_mob = new /mob/living/simple_animal/tomato(M.loc)
- if("mouse") new_mob = new /mob/living/simple_animal/mouse(M.loc)
- if("chicken") new_mob = new /mob/living/simple_animal/chicken(M.loc)
- if("cow") new_mob = new /mob/living/simple_animal/cow(M.loc)
- if("lizard") new_mob = new /mob/living/simple_animal/lizard(M.loc)
- else new_mob = new /mob/living/simple_animal/chick(M.loc)
- new_mob.universal_speak = 1
- if("human")
- new_mob = new /mob/living/carbon/human(M.loc)
-
- var/datum/preferences/A = new() //Randomize appearance for the human
- A.copy_to(new_mob)
-
- var/mob/living/carbon/human/H = new_mob
- ready_dna(H)
- if(H.dna)
- H.dna.mutantrace = pick("lizard","golem","slime","plant","fly","shadow","adamantine","skeleton",8;"")
- H.update_body()
- else
- return
-
- for (var/obj/effect/proc_holder/spell/S in M.spell_list)
- new_mob.spell_list += new S.type
-
- new_mob.a_intent = "harm"
- if(M.mind)
- M.mind.transfer_to(new_mob)
- else
- new_mob.key = M.key
-
- new_mob << "Your form morphs into that of a [randomize]."
-
- del(M)
- return new_mob
-
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index d3b734d6d2d..d1ce1991beb 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -135,3 +135,46 @@
var/mob/living/carbon/human/M = target
M.adjustBrainLoss(20)
M.hallucination += 20
+
+/obj/item/projectile/kinetic
+ name = "kinetic force"
+ icon_state = null
+ damage = 15
+ damage_type = BRUTE
+ flag = "bomb"
+ var/range = 2
+
+obj/item/projectile/kinetic/New()
+ var/turf/proj_turf = get_turf(src)
+ if(!istype(proj_turf, /turf))
+ return
+ var/datum/gas_mixture/environment = proj_turf.return_air()
+ var/pressure = environment.return_pressure()
+ if(pressure < 50)
+ name = "full strength kinetic force"
+ damage = 30
+ ..()
+
+/obj/item/projectile/kinetic/Range()
+ range--
+ if(range <= 0)
+ new /obj/item/effect/kinetic_blast(src.loc)
+ delete()
+
+/obj/item/projectile/kinetic/on_hit(var/atom/target)
+ var/turf/target_turf= get_turf(target)
+ if(istype(target_turf, /turf/simulated/mineral))
+ var/turf/simulated/mineral/M = target_turf
+ M.gets_drilled()
+ new /obj/item/effect/kinetic_blast(target_turf)
+ ..()
+
+/obj/item/effect/kinetic_blast
+ name = "kinetic explosion"
+ icon = 'icons/obj/projectiles.dmi'
+ icon_state = "kinetic_blast"
+ layer = 4.1
+
+/obj/item/effect/kinetic_blast/New()
+ spawn(4)
+ del(src)
\ No newline at end of file
diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/Chemistry-Colours.dm
index 5197fcf9e0b..d2f616a9f8a 100644
--- a/code/modules/reagents/Chemistry-Colours.dm
+++ b/code/modules/reagents/Chemistry-Colours.dm
@@ -1,35 +1,42 @@
/proc/GetColors(hex)
hex = uppertext(hex)
- var/hi1 = text2ascii(hex, 2)
- var/lo1 = text2ascii(hex, 3)
- var/hi2 = text2ascii(hex, 4)
- var/lo2 = text2ascii(hex, 5)
- var/hi3 = text2ascii(hex, 6)
- var/lo3 = text2ascii(hex, 7)
+ // No alpha set? Default to full alpha.
+ if(length(hex) == 7)
+ hex += "FF"
+ var/hi1 = text2ascii(hex, 2) // R
+ var/lo1 = text2ascii(hex, 3) // R
+ var/hi2 = text2ascii(hex, 4) // G
+ var/lo2 = text2ascii(hex, 5) // G
+ var/hi3 = text2ascii(hex, 6) // B
+ var/lo3 = text2ascii(hex, 7) // B
+ var/hi4 = text2ascii(hex, 8) // A
+ var/lo4 = text2ascii(hex, 9) // A
return list(((hi1>= 65 ? hi1-55 : hi1-48)<<4) | (lo1 >= 65 ? lo1-55 : lo1-48),
((hi2 >= 65 ? hi2-55 : hi2-48)<<4) | (lo2 >= 65 ? lo2-55 : lo2-48),
- ((hi3 >= 65 ? hi3-55 : hi3-48)<<4) | (lo3 >= 65 ? lo3-55 : lo3-48))
+ ((hi3 >= 65 ? hi3-55 : hi3-48)<<4) | (lo3 >= 65 ? lo3-55 : lo3-48),
+ ((hi4 >= 65 ? hi4-55 : hi4-48)<<4) | (lo4 >= 65 ? lo4-55 : lo4-48))
/proc/mix_color_from_reagents(var/list/reagent_list)
if(!reagent_list || !reagent_list.len) return 0
- var/list/rgbcolor = list(0,0,0)
+ var/list/rgbcolor = list(0,0,0,0)
var/finalcolor = 0
for(var/datum/reagent/re in reagent_list) // natural color mixing bullshit/algorithm
if(!finalcolor)
rgbcolor = GetColors(re.color)
finalcolor = re.color
else
- var/newcolor[3]
- var/prergbcolor[3]
+ var/newcolor[4]
+ var/prergbcolor[4]
prergbcolor = rgbcolor
newcolor = GetColors(re.color)
rgbcolor[1] = (prergbcolor[1]+newcolor[1])/2
rgbcolor[2] = (prergbcolor[2]+newcolor[2])/2
rgbcolor[3] = (prergbcolor[3]+newcolor[3])/2
+ rgbcolor[4] = (prergbcolor[4]+newcolor[4])/2
- finalcolor = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3])
+ finalcolor = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4])
return finalcolor
// This isn't a perfect color mixing system, the more reagents that are inside,
diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm
index 3e22bd7a6af..9a52bf80566 100644
--- a/code/modules/reagents/Chemistry-Holder.dm
+++ b/code/modules/reagents/Chemistry-Holder.dm
@@ -407,6 +407,11 @@ datum
return 1
+ add_reagent_list(var/list/list_reagents, var/list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15)
+ for(var/r_id in list_reagents)
+ var/amt = list_reagents[r_id]
+ add_reagent(r_id, amt, data)
+
remove_reagent(var/reagent, var/amount, var/safety)//Added a safety check for the trans_id_to
if(!isnum(amount)) return 1
@@ -485,5 +490,7 @@ datum
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
atom/proc/create_reagents(var/max_vol)
+ if(reagents)
+ reagents.delete()
reagents = new/datum/reagents(max_vol)
reagents.my_atom = src
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index e838b899e6e..7a41e3686ec 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -109,15 +109,15 @@
if(temp)
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list...
data["chemicals"] = chemicals
-
+
// update the ui if it exists, returns null if no ui is passed/found
- ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "chem_dispenser.tmpl", "Chem Dispenser 5000", 390, 610)
// when the ui is first opened this is the data it will use
- ui.set_initial_data(data)
+ ui.set_initial_data(data)
// open the new ui window
ui.open()
@@ -776,6 +776,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
/obj/item/toy/crayon/green = list("greencrayonpowder" = 10),
/obj/item/toy/crayon/blue = list("bluecrayonpowder" = 10),
/obj/item/toy/crayon/purple = list("purplecrayonpowder" = 10),
+ /obj/item/toy/crayon/mime = list("invisiblecrayonpowder" = 50),
//Blender Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index d660c999307..36b9c7b4777 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -209,7 +209,7 @@ datum
id = "water"
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
reagent_state = LIQUID
- color = "#0064C8" // rgb: 0, 100, 200
+ color = "#AAAAAA77" // rgb: 170, 170, 170, 77 (alpha)
reaction_turf(var/turf/simulated/T, var/volume)
if (!istype(T)) return
@@ -1291,7 +1291,7 @@ datum
id = "plasma"
description = "Plasma in its liquid form."
reagent_state = LIQUID
- color = "#E71B00" // rgb: 231, 27, 0
+ color = "#DB2D08" // rgb: 219, 45, 8
toxpwr = 3
on_mob_life(var/mob/living/M as mob)
@@ -1675,52 +1675,42 @@ datum
name = "Red Crayon Powder"
id = "redcrayonpowder"
colorname = "red"
- color = "#DA0000" // red
- New()
- ..()
crayonpowder/orange
name = "Orange Crayon Powder"
id = "orangecrayonpowder"
colorname = "orange"
color = "#FF9300" // orange
- New()
- ..()
-
crayonpowder/yellow
name = "Yellow Crayon Powder"
id = "yellowcrayonpowder"
colorname = "yellow"
color = "#FFF200" // yellow
- New()
- ..()
-
crayonpowder/green
name = "Green Crayon Powder"
id = "greencrayonpowder"
colorname = "green"
color = "#A8E61D" // green
- New()
- ..()
-
crayonpowder/blue
name = "Blue Crayon Powder"
id = "bluecrayonpowder"
colorname = "blue"
color = "#00B7EF" // blue
- New()
- ..()
crayonpowder/purple
name = "Purple Crayon Powder"
id = "purplecrayonpowder"
colorname = "purple"
color = "#DA00FF" // purple
- New()
- ..()
+
+ crayonpowder/invisible
+ name = "Invisible Crayon Powder"
+ id = "invisiblecrayonpowder"
+ colorname = "invisible"
+ color = "#FFFFFF00" // white + no alpha
/////////////////////////Food Reagents////////////////////////////
diff --git a/code/modules/reagents/reagent_containers/food/condiment.dm b/code/modules/reagents/reagent_containers/food/condiment.dm
index e07f14f6eda..fd0051502d3 100644
--- a/code/modules/reagents/reagent_containers/food/condiment.dm
+++ b/code/modules/reagents/reagent_containers/food/condiment.dm
@@ -98,10 +98,11 @@
else
name = "misc Condiment Bottle"
+ main_reagent = reagents.get_master_reagent_name()
if (reagents.reagent_list.len==1)
- desc = "Looks like it is [main_reagent], but you are not sure."
+ desc = "Looks like it is [lowertext(main_reagent)], but you are not sure."
else
- desc = "A mixture of various condiments. [main_reagent] is one of them."
+ desc = "A mixture of various condiments. [lowertext(main_reagent)] is one of them."
icon_state = "mixedcondiments"
else
icon_state = "emptycondiment"
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 972c9cc3057..0c16222b863 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -242,6 +242,13 @@
*/
interact(user, 0)
+// hostile mob escape from disposals
+/obj/machinery/disposal/attack_animal(var/mob/living/simple_animal/M)
+ if(M.environment_smash)
+ visible_message("[M.name] smashes [src] apart!")
+ del(src)
+ return
+
// user interaction
/obj/machinery/disposal/interact(mob/user, var/ai=0)
diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/generic_steps.dm
index f810bec205d..260f92e9efd 100644
--- a/code/modules/surgery/generic_steps.dm
+++ b/code/modules/surgery/generic_steps.dm
@@ -58,7 +58,7 @@
//saw bone
/datum/surgery_step/saw
- implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
+ implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
time = 64
/datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index 6fbc2f55fbd..f55f2888677 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -151,6 +151,30 @@
return update_organ_icon()
+/obj/item/proc/item_heal_robotic(var/mob/living/carbon/human/H, var/mob/user, var/brute, var/burn)
+ var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
+
+ var/dam //changes repair text based on how much brute/burn was supplied
+
+ if(brute > burn)
+ dam = 1
+ else
+ dam = 0
+
+ if(affecting.status == ORGAN_ROBOTIC)
+ if(brute > 0 && affecting.brute_dam > 0 || burn > 0 && affecting.burn_dam > 0)
+ affecting.heal_damage(brute,burn,1)
+ H.update_damage_overlays(0)
+ H.updatehealth()
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("[user] has fixed some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting.getDisplayName()]!"), 1)
+ return
+ else
+ user << "[H]'s [affecting.getDisplayName()] is already in good condition"
+ return
+ else
+ return
+
//Returns total damage...kinda pointless really
/obj/item/organ/limb/proc/get_damage()
return brute_dam + burn_dam
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index e456109a954..91734c1b63e 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -85,6 +85,7 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "saw"
hitsound = 'sound/weapons/circsawhit.ogg'
+ throwhitsound = 'sound/weapons/pierce.ogg'
flags = CONDUCT
force = 15.0
w_class = 3.0
diff --git a/code/unused/hivebot/life.dm b/code/unused/hivebot/life.dm
index 33198a5f310..35f73c2b97c 100644
--- a/code/unused/hivebot/life.dm
+++ b/code/unused/hivebot/life.dm
@@ -128,6 +128,8 @@
src.sight &= ~SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ if(see_override)
+ see_invisible = see_override
if (src.healths)
if (src.stat != 2)
diff --git a/config/admins.txt b/config/admins.txt
index af55e1f1acf..68a07ebe030 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -10,6 +10,7 @@
rolan7 = Game Master
quarxink = Game Master
+adrix89 = Game Master
tle = Game Master
xsi = Game Master
scaredofshadows = Game Master
@@ -53,4 +54,4 @@ kazeespada = Game Master
rumia29 = Game Master
bobylein = Game Master
sirbayer = Game Master
-hornygranny = Game Master
\ No newline at end of file
+hornygranny = Game Master
diff --git a/html/changelog.html b/html/changelog.html
index c4fecf62d5c..c18227ee22a 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -35,7 +35,7 @@