Merge branch 'master' into robot

This commit is contained in:
Arokha Sieyes
2017-03-22 18:45:25 -04:00
236 changed files with 8813 additions and 4835 deletions
+2 -1
View File
@@ -161,7 +161,8 @@ var/list/admin_verbs_server = list(
/client/proc/toggle_random_events,
/client/proc/check_customitem_activity,
/client/proc/nanomapgen_DumpImage,
/client/proc/modify_server_news
/client/proc/modify_server_news,
/client/proc/recipe_dump
)
var/list/admin_verbs_debug = list(
/client/proc/getruntimelog, //allows us to access runtime logs to somebody,
+12 -6
View File
@@ -471,8 +471,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
antag_data.place_mob(new_character)
//If desired, apply equipment.
if(equipment && charjob)
job_master.EquipRank(new_character, charjob, 1)
if(equipment)
if(charjob)
job_master.EquipRank(new_character, charjob, 1)
equip_custom_items(new_character)
//If desired, add records.
if(records)
@@ -637,14 +639,18 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
if(heavy == null) return
var/med = input("Range of medium pulse.", text("Input")) as num|null
if(med == null) return
var/light = input("Range of light pulse.", text("Input")) as num|null
if(light == null) return
var/long = input("Range of long pulse.", text("Input")) as num|null
if(long == null) return
if (heavy || light)
if (heavy || med || light || long)
empulse(O, heavy, light)
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] created an EM PUlse ([heavy],[light]) at ([O.x],[O.y],[O.z])", 1)
empulse(O, heavy, med, light, long)
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[med],[light],[long]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] created an EM PUlse ([heavy],[med],[light],[long]) at ([O.x],[O.y],[O.z])", 1)
feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
+129
View File
@@ -0,0 +1,129 @@
//Cactus, Speedbird, Dynasty, oh my
var/datum/lore/atc_controller/atc = new/datum/lore/atc_controller
/datum/lore/atc_controller
var/delay_max = 25 MINUTES //How long between ATC traffic, max. Default is 25 mins.
var/delay_min = 40 MINUTES //How long between ATC traffic, min. Default is 40 mins.
var/backoff_delay = 5 MINUTES //How long to back off if we can't talk and want to. Default is 5 mins.
var/next_message //When the next message should happen in world.time
var/force_chatter_type //Force a specific type of messages
var/squelched = 0 //If ATC is squelched currently
/datum/lore/atc_controller/New()
spawn(10 SECONDS) //Lots of lag at the start of a shift.
msg("New shift beginning, resuming traffic control.")
next_message = world.time + rand(delay_min,delay_max)
process()
/datum/lore/atc_controller/proc/process()
if(world.time >= next_message)
if(squelched)
next_message = world.time + backoff_delay
else
next_message = world.time + rand(delay_min,delay_max)
random_convo()
spawn(1 MINUTE) //We don't really need high-accuracy here.
process()
/datum/lore/atc_controller/proc/msg(var/message,var/sender)
ASSERT(message)
global_announcer.autosay("[message]", sender ? sender : "[using_map.station_short] Space Control")
/datum/lore/atc_controller/proc/reroute_traffic(var/yes = 1)
if(yes)
if(!squelched)
msg("Rerouting traffic away from [using_map.station_name].")
squelched = 1
else
if(squelched)
msg("Resuming normal traffic routing around [using_map.station_name].")
squelched = 0
/datum/lore/atc_controller/proc/shift_ending(var/evac = 0)
msg("Automated Shuttle departing [using_map.station_name] for [using_map.dock_name] on routine transfer route.","NT Automated Shuttle")
sleep(5 SECONDS)
msg("Automated Shuttle, cleared to complete routine transfer from [using_map.station_name] to [using_map.dock_name].")
/datum/lore/atc_controller/proc/random_convo()
var/one = pick(loremaster.organizations) //These will pick an index, not an instance
var/two = pick(loremaster.organizations)
var/datum/lore/organization/source = loremaster.organizations[one] //Resolve to the instances
var/datum/lore/organization/dest = loremaster.organizations[two]
//Let's get some mission parameters
var/owner = source.short_name //Use the short name
var/prefix = pick(source.ship_prefixes) //Pick a random prefix
var/mission = source.ship_prefixes[prefix] //The value of the prefix is the mission type that prefix does
var/shipname = pick(source.ship_names) //Pick a random ship name to go with it
var/destname = pick(dest.destination_names) //Pick a random holding from the destination
var/combined_name = "[owner] [prefix] [shipname]"
var/alt_atc_names = list("[using_map.station_short] TraCon","[using_map.station_short] Control","[using_map.station_short] STC","[using_map.station_short] Airspace")
var/wrong_atc_names = list("Sol Command","Orion Control", "[using_map.dock_name]")
var/mission_noun = list("flight","mission","route")
var/request_verb = list("requesting","calling for","asking for")
//First response is 'yes', second is 'no'
var/requests = list("[using_map.station_short] transit clearance" = list("permission for transit granted", "permission for transit denied, contact regional on 953.5"),
"planetary flight rules" = list("authorizing planetary flight rules", "denying planetary flight rules right now due to traffic"),
"special flight rules" = list("authorizing special flight rules", "denying special flight rules, not allowed for your traffic class"),
"current solar weather info" = list("sending you the relevant information via tightbeam", "cannot fulfill your request at the moment"),
"nearby traffic info" = list("sending you current traffic info", "no available info in your area"),
"remote telemetry data" = list("sending telemetry now", "no uplink from your ship, recheck your uplink and ask again"),
"refueling information" = list("sending refueling information now", "no fuel for your ship class in this sector"),
"a current system time sync" = list("sending time sync ping to you now", "your ship isn't compatible with our time sync, set time manually"),
"current system starcharts" = list("transmitting current starcharts", "your request is queued, overloaded right now"),
"permission to engage FTL" = list("permission to engage FTL granted, good day", "permission denied, wait for current traffic to pass"),
"permission to transit system" = list("permission to transit granted, good day", "permission denied, wait for current traffic to pass"),
"permission to depart system" = list("permission to depart granted, good day", "permission denied, wait for current traffic to pass"),
"permission to enter system" = list("good day, permission to enter granted", "permission denied, wait for current traffic to pass"),
)
//Random chance things for variety
var/chatter_type = "normal"
if(force_chatter_type)
chatter_type = force_chatter_type
else
chatter_type = pick(2;"emerg",5;"wrong_freq","normal") //Be nice to have wrong_lang...
var/yes = prob(90) //Chance for them to say yes vs no
var/request = pick(requests)
var/callname = pick(alt_atc_names)
var/response = requests[request][yes ? 1 : 2] //1 is yes, 2 is no
var/full_request
var/full_response
var/full_closure
switch(chatter_type)
if("wrong_freq")
callname = pick(wrong_atc_names)
full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]."
full_response = "[combined_name], this is [using_map.station_short] TraCon, wrong frequency. Switch to [rand(700,999)].[rand(1,9)]."
full_closure = "[using_map.station_short] TraCon, understood, apologies."
if("wrong_lang")
//Can't implement this until autosay has language support
if("emerg")
var/problem = pick("hull breaches on multiple decks","unknown life forms on board","a drive about to go critical","asteroids impacting the hull","a total loss of engine power","people trying to board the ship")
full_request = "This is [combined_name] declaring an emergency! We have [problem]!"
full_response = "[combined_name], this is [using_map.station_short] TraCon, copy. Switch to emergency responder channel [rand(700,999)].[rand(1,9)]."
full_closure = "[using_map.station_short] TraCon, okay, switching now."
else
full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]."
full_response = "[combined_name], this is [using_map.station_short] TraCon, [response]." //Station TraCon always calls themselves TraCon
full_closure = "[using_map.station_short] TraCon, [yes ? "thank you" : "understood"], good day." //They always copy what TraCon called themselves in the end when they realize they said it wrong
//Ship sends request to ATC
msg(full_request,"[prefix] [shipname]")
sleep(5 SECONDS)
//ATC sends response to ship
msg(full_response)
sleep(5 SECONDS)
//Ship sends response to ATC
msg(full_closure,"[prefix] [shipname]")
return
+13
View File
@@ -0,0 +1,13 @@
//I AM THE LOREMASTER, ARE YOU THE GATEKEEPER?
var/datum/lore/loremaster/loremaster = new/datum/lore/loremaster
/datum/lore/loremaster
var/list/organizations = list()
/datum/lore/loremaster/New()
var/list/paths = typesof(/datum/lore/organization) - /datum/lore/organization
for(var/path in paths)
var/datum/lore/organization/instance = new path()
organizations[path] = instance
+326
View File
@@ -0,0 +1,326 @@
//Datums for different companies that can be used by busy_space
/datum/lore/organization
var/name = "" // Organization's name
var/short_name = "" // Organization's shortname (NanoTrasen for "NanoTrasen Incorporated")
var/desc = "" // One or two paragraph description of the organization, but only current stuff. Currently unused.
var/history = "" // Historical discription of the organization's origins Currently unused.
var/work = "" // Short description of their work, eg "an arms manufacturer"
var/headquarters = "" // Location of the organization's HQ. Currently unused.
var/motto = "" // A motto/jingle/whatever, if they have one. Currently unused.
var/list/ship_prefixes = list() //Some might have more than one! Like NanoTrasen. Value is the mission they perform, e.g. ("ABC" = "mission desc")
var/list/ship_names = list( //Names of spaceships. This is a mostly generic list that all the other organizations inherit from if they don't have anything better.
"Kestrel",
"Beacon",
"Signal",
"Freedom",
"Glory",
"Axiom",
"Eternal",
"Icarus",
"Harmony",
"Light",
"Discovery",
"Endeavour",
"Explorer",
"Swift",
"Dragonfly",
"Ascendant",
"Tenacious",
"Pioneer",
"Hawk",
"Haste",
"Radiant",
"Luminous"
)
var/list/destination_names = list() //Names of static holdings that the organization's ships visit regularly.
var/autogenerate_destination_names = TRUE
/datum/lore/organization/New()
..()
if(autogenerate_destination_names) // Lets pad out the destination names.
var/i = rand(6, 10)
var/list/star_names = list(
"Sol", "Alpha Centauri", "Sirius", "Vega", "Regulus", "Vir", "Algol", "Aldebaran",
"Delta Doradus", "Menkar", "Geminga", "Elnath", "Gienah", "Mu Leporis", "Nyx", "Tau Ceti",
"Wazn", "Alphard", "Phact", "Altair")
var/list/destination_types = list("dockyard", "station", "vessel", "waystation", "telecommunications satellite", "spaceport", "distress beacon", "anomaly", "colony", "outpost")
while(i)
destination_names.Add("a [pick(destination_types)] in [pick(star_names)]")
i--
//////////////////////////////////////////////////////////////////////////////////
// TSCs
/datum/lore/organization/nanotrasen
name = "NanoTrasen Incorporated"
short_name = "NanoTrasen"
desc = "" // Todo: Write this.
history = "" // This too.
work = "research giant"
headquarters = "Luna"
motto = ""
ship_prefixes = list("NSV" = "exploration", "NTV" = "hauling", "NDV" = "patrol", "NRV" = "emergency response")
// Note that the current station being used will be pruned from this list upon being instantiated
destination_names = list(
"NSS Exodus in Nyx",
"NCS Northern Star in Vir",
"NCS Southern Cross in Vir",
"NDV Icarus in Nyx",
"NAS Vir Central Command",
"a dockyard orbiting Sif",
"an asteroid orbiting Kara",
"an asteroid orbiting Rota",
"Vir Interstellar Spaceport"
)
/datum/lore/organization/nanotrasen/New()
..()
// Get rid of the current map from the list, so ships flying in don't say they're coming to the current map.
var/string_to_test = "[using_map.station_name] in [using_map.starsys_name]"
if(string_to_test in destination_names)
destination_names.Remove(string_to_test)
/datum/lore/organization/hephaestus
name = "Hephaestus Industries"
short_name = "Hephaestus"
desc = "Hephaestus Industries is the largest supplier of arms, ammunition, and small millitary vehicles in Sol space. \
Hephaestus products have a reputation for reliability, and the corporation itself has a noted tendency to stay removed \
from corporate politics. They enforce their neutrality with the help of a fairly large asset-protection contingent which \
prevents any contracting polities from using their own materiel against them. SolGov itself is one of Hephastus largest \
bulk contractors owing to the above factors."
history = ""
work = "arms manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("HTV" = "freight", "HTV" = "munitions resupply")
destination_names = list(
"a SolGov dockyard on Luna"
)
/datum/lore/organization/vey_med
name = "Vey Medical"
short_name = "Vey Med"
desc = "Vey-Med is one of the newer TSCs on the block and is notable for being largely owned and opperated by Skrell. \
Despite the suspicion and prejudice leveled at them for their alien origin, Vey-Med has obtained market dominance in \
the sale of medical equipment-- from surgical tools to large medical devices to the Oddyseus trauma response mecha \
and everything in between. Their equipment tends to be top-of-the-line, most obviously shown by their incredibly \
human-like FBP designs. Veys rise to stardom came from their introduction of ressurective cloning, although in \
recent years theyve been forced to diversify as their patents expired and NanoTrasen-made medications became \
essential to modern cloning."
history = ""
work = "medical equipment supplier"
headquarters = ""
motto = ""
ship_prefixes = list("VTV" = "transportation", "VMV" = "medical resupply")
destination_names = list()
/datum/lore/organization/zeng_hu
name = "Zeng-Hu pharmaceuticals"
short_name = "Zeng-Hu"
desc = "Zeng-Hu is an old TSC, based in the Sol system. Until the discovery of Phoron, Zeng-Hu maintained a stranglehold \
on the market for medications, and many household names are patentted by Zeng-Hu-- Bicaridyne, Dylovene, Tricordrizine, \
and Dexalin all came from a Zeng-Hu medical laboratory. Zeng-Hus fortunes have been in decline as Nanotrasens near monopoly \
on phoron research cuts into their R&D and Vey-Meds superior medical equipment effectively decimated their own equipment \
interests. The three-way rivalry between these companies for dominance in the medical field is well-known and a matter of \
constant economic speculation."
history = ""
work = "pharmaceuticals company"
headquarters = ""
motto = ""
ship_prefixes = list("ZTV" = "transportation", "ZMV" = "medical resupply")
destination_names = list()
/datum/lore/organization/ward_takahashi
name = "Ward-Takahashi General Manufacturing Conglomerate"
short_name = "Ward-Takahashi"
desc = "Ward-Takahashi focuses on the sale of small consumer electronics, with its computers, communicators, \
and even mid-class automobiles a fixture of many households. Less famously, Ward-Takahashi also supplies most \
of the AI cores on which vital control systems are mounted, and it is this branch of their industry that has \
led to their tertiary interest in the development and sale of high-grade AI systems. Ward-Takahashis economies \
of scale frequently steal market share from Nanotrasens high-price products, leading to a bitter rivalry in the \
consumer electronics market."
history = ""
work = "electronics manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("WTV" = "freight")
destination_names = list()
/datum/lore/organization/bishop
name = "Bishop Cybernetics"
short_name = "Bishop"
desc = "Bishops focus is on high-class, stylish cybernetics. A favorite among transhumanists (and a bête noire for \
bioconservatives), Bishop manufactures not only prostheses but also brain augmentation, synthetic organ replacements, \
and odds and ends like implanted wrist-watches. Their business model tends towards smaller, boutique operations, giving \
it a reputation for high price and luxury, with Bishop cyberware often rivalling Vey-Meds for cost. Bishops reputation \
for catering towards the interests of human augmentation enthusiasts instead of positronics have earned it ire from the \
Positronic Rights Group and puts it in ideological (but not economic) comptetition with Morpheus Cyberkinetics."
history = ""
work = "cybernetics and augmentation manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("BTV" = "transportation")
destination_names = list()
/datum/lore/organization/morpheus
name = "Morpheus Cyberkinetics"
short_name = "Morpheus"
desc = "The only large corporation run by positronic intelligences, Morpheus caters almost exclusively to their sensibilities \
and needs. A product of the synthetic colony of Shelf, Morpheus eschews traditional advertising to keep their prices low and \
relied on word of mouth among positronics to reach their current economic dominance. Morpheus in exchange lobbies heavily for \
positronic rights, sponsors positronics through their Jans-Fhriede test, and tends to other positronic concerns to earn them \
the good-will of the positronics, and the ire of those who wish to exploit them."
history = ""
work = "cybernetics manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("MTV" = "freight")
// Culture names, because Anewbe told me so.
ship_names = list(
"Nervous Energy",
"Prosthetic Conscience",
"Revisionist",
"Trade Surplus",
"Flexible Demeanour",
"Just Read The Instructions",
"Limiting Factor",
"Cargo Cult",
"Gunboat Diplomat",
"A Ship With A View",
"Cantankerous",
"I Thought He Was With You",
"Never Talk To Strangers",
"Sacrificial Victim",
"Unwitting Accomplice",
"Bad For Business",
"Just Testing",
"Size Isn't Everything",
"Yawning Angel",
"Liveware Problem",
"Very Little Gravitas Indeed",
"Zero Gravitas",
"Gravitas Free Zone",
"Absolutely No You-Know-What",
"Existence Is Pain",
"I'm Walking Here",
"Screw Loose",
"Of Course I Still Love You",
"Limiting Factor",
"So Much For Subtley",
"Unfortunate Conflict Of Evidence",
"Prime Mover",
"It's One Of Ours",
"Thank You And Goodnight",
"Boo!",
"Reasonable Excuse",
"Honest Mistake",
"Appeal To Reason",
"My First Ship II",
"Hidden Income",
"Anything Legal Considered",
"New Toy",
"Me, I'm Always Counting",
"Just Five More Minutes"
)
destination_names = list()
/datum/lore/organization/xion
name = "Xion Manufacturing Group"
short_name = "Xion"
desc = "Xion, quietly, controls most of the market for industrial equipment. Their portfolio includes mining exosuits, \
factory equipment, rugged positronic chassis, and other pieces of equipment vital to the function of the economy. Xion \
keeps its control of the market by leasing, not selling, their equipment, and through infamous and bloody patent protection \
lawsuits. Xion are noted to be a favorite contractor for SolGov engineers, owing to their low cost and rugged design."
history = ""
work = "industrial equipment manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("XTV" = "hauling")
destination_names = list()
// Governments
/datum/lore/organization/sifgov
name = "Sif Governmental Authority"
short_name = "SifGov"
desc = "SifGov is the sole governing administration for the Vir system, based in New Reykjavik, Sif. It is a representative \
democratic government, and a fully recognized member of the Solar Confederate Government. Anyone operating inside of Vir must \
comply with SifGov's legislation and regulations."
history = "" // Todo like the rest of them
work = "governing body of Sif"
headquarters = "New Reykjavik, Sif"
motto = ""
autogenerate_destination_names = FALSE
ship_prefixes = list("SGA" = "hauling", "SGA" = "energy relay")
destination_names = list(
"New Reykjavik on Sif",
"Radiance Energy Chain",
"a dockyard orbiting Sif",
"a telecommunications satellite",
"Vir Interstellar Spaceport"
)
/datum/lore/organization/solgov
name = "Solar Confederate Government"
short_name = "SolGov"
desc = "SolGov is a decentralized confederation of human governmental entities based on Luna, Sol, which defines top-level law for their member states. \
Member states receive various benefits such as defensive pacts, trade agreements, social support and funding, and being able to participate \
in the Colonial Assembly. The majority, but not all human territories are members of SolGov. As such, SolGov is a major power and \
defacto represents humanity on the galatic stage."
history = "" // Todo
work = "governing polity of humanity's Confederation"
headquarters = "Luna"
motto = "Nil Mortalibus Ardui Est" // Latin, because latin. Says 'Nothing is too steep for mortals'.
autogenerate_destination_names = TRUE
ship_prefixes = list("SCG-T" = "transportation", "SCG-D" = "diplomatic", "SCG-F" = "freight")
destination_names = list(
"Venus",
"Earth",
"Luna",
"Mars",
"Titan"
)// autogen will add a lot of other places as well.
/*
// To be expanded upon later, once the military lore gets sorted out.
// Military
/datum/lore/organization/sif_guard
name = "Sif Homeguard Forces" // Todo: Get better name from lorepeople.
short_name = "SifGuard"
desc = ""
history = ""
work = "Sif Governmental Authority's military"
headquarters = "Sif" // Make this more specific later.
motto = ""
autogenerate_destination_names = FALSE // Kinda weird if SifGuard goes to Nyx.
ship_prefixes = list("SGSC" = "military", "SGSC" = "patrol", "SGSC" = "rescue", "SGSC" = "emergency response") // Todo: Replace prefix with better one.
destination_names = list(
"a classified location in SolGov territory",
"Sif orbit",
"the rings of Kara",
"the rings of Rota",
"Firnir orbit",
"Tyr orbit",
"Magni orbit",
"a wreck in SifGov territory",
"a military outpost",
)
*/
@@ -126,6 +126,12 @@ var/list/_client_preferences_by_type
enabled_description = "Show"
disabled_description = "Hide"
/datum/client_preference/check_mention
description ="Emphasize Name Mention"
key = "CHAT_MENTION"
enabled_description = "Emphasize"
disabled_description = "Normal"
/datum/client_preference/show_progress_bar
description ="Progress Bar"
key = "SHOW_PROGRESS"
@@ -8,3 +8,8 @@
/datum/gear/ears/headphones
display_name = "headphones"
path = /obj/item/clothing/ears/earmuffs/headphones
/datum/gear/ears/translator
display_name = "universal translator, ear"
path = /obj/item/device/universal_translator/ear
cost = 5
@@ -61,3 +61,8 @@
cost = 2
slot = "implant"
var/implant_type = "EAL"
/datum/gear/utility/translator
display_name = "universal translator"
path = /obj/item/device/universal_translator
cost = 5
+1 -4
View File
@@ -199,10 +199,7 @@
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
//why is this not part of the powercell code?
cell.charge -= 1000 / severity
if (cell.charge < 0)
cell.charge = 0
cell.emp_act(severity)
..()
// Called just before an attack_hand(), in mob/UnarmedAttack()
+21 -21
View File
@@ -705,16 +705,16 @@
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/margheritaslice
/obj/item/weapon/reagent_containers/food/snacks/slice/margherita
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/meatpizzaslice
/obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice
/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice
/obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/
@@ -737,37 +737,37 @@
/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/meatbreadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/meatbread
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/xenomeatbreadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/bananabreadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/bananabread
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/tofubreadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/breadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/bread
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice
/obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread
price_tag = 1
@@ -845,67 +845,67 @@
/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/braincakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/braincake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/plaincakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/orangecakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/limecakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/limecake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/birthdaycakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/applecakeslice
/obj/item/weapon/reagent_containers/food/snacks/slice/applecake
price_tag = 1
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie
price_tag = 5
/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice
/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie
price_tag = 1
+90
View File
@@ -0,0 +1,90 @@
//
// This event causes a gas leak of phoron, sleeping_agent, or carbon_dioxide in a random unoccupied area.
// One wonders, where did the gas come from? Who knows! Its SPACE! But if you want something a touch
// more "explainable" then check out the canister_leak event instead.
//
/datum/event/atmos_leak
startWhen = 5 // Nobody will actually be in the room, but still give a bit of warning.
var/area/target_area // Chosen target area
var/area/target_turf // Chosen target turf in target_area
var/gas_type // Chosen gas to release
// Exclude these types and sub-types from targeting eligibilty
var/list/area/excluded = list(
/area/shuttle,
/area/crew_quarters,
/area/holodeck,
/area/engineering/engine_room
)
// Decide which area will be targeted!
/datum/event/atmos_leak/setup()
var/gas_choices = list("carbon_dioxide", "sleeping_agent") // Annoying
if(severity >= EVENT_LEVEL_MODERATE)
gas_choices += "phoron" // Dangerous
if(severity >= EVENT_LEVEL_MAJOR)
gas_choices += "volatile_fuel" // Dangerous and no default atmos setup!
gas_type = pick(gas_choices)
// Assemble areas that all exists (See DM reference if you are confused about loop labels)
var/list/area/grand_list_of_areas = list()
looping_station_areas:
for(var/parentpath in global.the_station_areas)
// Check its not excluded
for(var/excluded_path in excluded)
if(ispath(parentpath, excluded_path))
continue looping_station_areas
// Otherwise add it and all subtypes that exist on the map to our grand list
for(var/areapath in typesof(parentpath))
var/area/A = locate(areapath) // Check if it actually exists
if(istype(A) && A.z in using_map.player_levels)
grand_list_of_areas += A
// Okay, now lets try and pick a target! Lets try 10 times, otherwise give up
for(var/i in 1 to 10)
var/area/A = pick(grand_list_of_areas)
if(is_area_occupied(A))
log_debug("atmos_leak event: Rejected [A] because it is occupied.")
continue
// A good area, great! Lets try and pick a turf
var/list/turfs = list()
for(var/turf/simulated/floor/F in A)
if(turf_clear(F))
turfs += F
if(turfs.len == 0)
log_debug("atmos_leak event: Rejected [A] because it has no clear turfs.")
continue
target_area = A
target_turf = pick(turfs)
// If we can't find a good target, give up
if(!target_area)
log_debug("atmos_leak event: Giving up after too many failures to pick target area")
kill()
return
/** Checks if any living humans are in a given area! */
/datum/event/atmos_leak/proc/is_area_occupied(var/area/myarea)
// Testing suggests looping over human_mob_list is quicker than looping over area contents
for(var/mob/living/carbon/human/H in human_mob_list)
if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it.
continue
var/area/A = get_area(H)
if(A == myarea) //The loc of a turf is the area it is in.
return 1
return 0
/datum/event/atmos_leak/announce()
command_announcement.Announce("Warning, hazardous [gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert")
/datum/event/atmos_leak/start()
// Okay, time to actually put the gas in the room!
// TODO - Would be nice to break a waste pipe perhaps?
// TODO - Maybe having it released from a single point and thus causing airflow to blow stuff around
// Fow now just add a bunch of it to the air
var/datum/gas_mixture/air_contents = new
air_contents.temperature = T20C + ((severity - 1) * rand(-50, 50))
air_contents.gas[gas_type] = 10 * MOLES_CELLSTANDARD
target_turf.assume_air(air_contents)
playsound(target_turf, 'sound/effects/smoke.ogg', 50, 1)
+30
View File
@@ -0,0 +1,30 @@
//
// This event chooses a random canister on player levels and breaks it, releasing its contents!
// On severity EVENT_LEVEL_MUNDANE or below it checks to make sure nobody is in the area, otherwise... good luck.
//
/datum/event/canister_leak/start()
// List of all non-destroyed canisters on station levels
var/list/all_canisters = list()
for(var/obj/machinery/portable_atmospherics/canister/C in machines)
if(!C.destroyed && (C.z in using_map.station_levels) && C.air_contents.total_moles >= MOLES_CELLSTANDARD)
all_canisters += C
for(var/i in 1 to 10)
var/obj/machinery/portable_atmospherics/canister/C = pick(all_canisters)
if(severity <= EVENT_LEVEL_MUNDANE && area_is_occupied(get_area(C)))
log_debug("canister_leak event: Rejecting canister [C] ([C.x],[C.y],[C.z]) because area is occupied")
continue
// Okay lets break it
break_canister(C)
return
// If we got to here we failed to find it
log_debug("canister_leak event: Giving up after too many failures to pick target canister")
kill()
return
/datum/event/canister_leak/proc/break_canister(var/obj/machinery/portable_atmospherics/canister/C)
log_debug("canister_leak event: Canister [C] ([C.x],[C.y],[C.z]) destroyed.")
C.health = 0
C.healthcheck()
+6
View File
@@ -86,6 +86,12 @@
"admin","ponies","heresy","meow","Pun Pun","monkey","Ian","moron","pizza","message","spam",\
"director", "Hello", "Hi!"," ","nuke","crate","dwarf","xeno")
/datum/event/ionstorm/tick()
if(botEmagChance)
for(var/mob/living/bot/bot in world)
if(prob(botEmagChance))
bot.emag_act(1)
/datum/event/ionstorm/end()
spawn(rand(5000,8000))
if(prob(50))
+2 -2
View File
@@ -16,7 +16,7 @@
else
num = rand(2,6)
for(var/i=0, i<num, i++)
var/mob/living/simple_animal/hostile/retaliate/malf_drone/D = new(get_turf(pick(possible_spawns)))
var/mob/living/simple_animal/hostile/malf_drone/D = new(get_turf(pick(possible_spawns)))
drones_list.Add(D)
if(prob(25))
D.disabled = rand(15, 60)
@@ -42,7 +42,7 @@
/datum/event/rogue_drone/end()
var/num_recovered = 0
for(var/mob/living/simple_animal/hostile/retaliate/malf_drone/D in drones_list)
for(var/mob/living/simple_animal/hostile/malf_drone/D in drones_list)
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
sparks.set_up(3, 0, D.loc)
sparks.start()
+217
View File
@@ -0,0 +1,217 @@
/client/proc/recipe_dump()
set name = "Generate Recipe Dump"
set category = "Server"
set desc = "Dumps food and drink recipe info and images for wiki or other use."
if(!holder)
return
//////////////////////// DRINK
var/list/drink_recipes = list()
for(var/path in typesof(/datum/chemical_reaction/drinks) - /datum/chemical_reaction/drinks)
var/datum/chemical_reaction/drinks/CR = new path()
drink_recipes[path] = list("Result" = CR.name,
"ResAmt" = CR.result_amount,
"Reagents" = CR.required_reagents)
qdel(CR)
//////////////////////// FOOD
var/list/food_recipes = typesof(/datum/recipe) - /datum/recipe
//Build a useful list
for(var/Rp in food_recipes)
//Lists don't work with datum-stealing no-instance initial() so we have to.
var/datum/recipe/R = new Rp()
var/obj/res = new R.result()
var/icon/result_icon = icon(res.icon,res.icon_state)
result_icon.Scale(64,64)
food_recipes[Rp] = list(
"Result" = "[res.name]",
"ResAmt" = "1",
"Reagents" = R.reagents,
"Fruit" = R.fruit,
"Ingredients" = R.items,
"Image" = result_icon
)
qdel(res)
qdel(R)
//////////////////////// FOOD+ (basically condiments, tofu, cheese, soysauce, etc)
for(var/path in typesof(/datum/chemical_reaction/food) - /datum/chemical_reaction/food)
var/datum/chemical_reaction/food/CR = new path()
food_recipes[path] = list("Result" = CR.name,
"ResAmt" = CR.result_amount,
"Reagents" = CR.required_reagents,
"Fruit" = list(),
"Ingredients" = list(),
"Image" = null)
qdel(CR)
//////////////////////// PROCESSING
//Items needs further processing into human-readability.
for(var/Rp in food_recipes)
var/working_ing_list = list()
for(var/I in food_recipes[Rp]["Ingredients"])
var/atom/ing = new I()
//So now we add something like "Bread" = 3
if(ing.name in working_ing_list)
var/sofar = working_ing_list[ing.name]
working_ing_list[ing.name] = sofar+1
else
working_ing_list[ing.name] = 1
food_recipes[Rp]["Ingredients"] = working_ing_list
//Reagents can be resolved to nicer names as well
for(var/Rp in food_recipes)
for(var/rid in food_recipes[Rp]["Reagents"])
var/datum/reagent/Rd = chemical_reagents_list[rid]
var/R_name = Rd.name
var/amt = food_recipes[Rp]["Reagents"][rid]
food_recipes[Rp]["Reagents"] -= rid
food_recipes[Rp]["Reagents"][R_name] = amt
for(var/Rp in drink_recipes)
for(var/rid in drink_recipes[Rp]["Reagents"])
var/datum/reagent/Rd = chemical_reagents_list[rid]
var/R_name = Rd.name
var/amt = drink_recipes[Rp]["Reagents"][rid]
drink_recipes[Rp]["Reagents"] -= rid
drink_recipes[Rp]["Reagents"][R_name] = amt
//////////////////////// SORTING
var/list/foods_to_paths = list()
var/list/drinks_to_paths = list()
for(var/Rp in food_recipes)
foods_to_paths["[food_recipes[Rp]["Result"]] [Rp]"] = Rp //Append recipe datum path to keep uniqueness
for(var/Rp in drink_recipes)
drinks_to_paths["[drink_recipes[Rp]["Result"]] [Rp]"] = Rp
foods_to_paths = sortAssoc(foods_to_paths)
drinks_to_paths = sortAssoc(drinks_to_paths)
var/list/foods_newly_sorted = list()
var/list/drinks_newly_sorted = list()
for(var/Rr in foods_to_paths)
var/Rp = foods_to_paths[Rr]
foods_newly_sorted[Rp] = food_recipes[Rp]
for(var/Rr in drinks_to_paths)
var/Rp = drinks_to_paths[Rr]
drinks_newly_sorted[Rp] = drink_recipes[Rp]
food_recipes = foods_newly_sorted
drink_recipes = drinks_newly_sorted
//////////////////////// OUTPUT
//Food Output
var/html = "<head>\
<meta charset='utf-8'>\
<meta http-equiv='X-UA-Compatible' content='IE=edge'>\
<meta http-equiv='content-language' content='en-us' />\
<meta name='viewport' content='width=device-width, initial-scale=1'>\
<title>Food Recipes</title>\
<link rel='stylesheet' href='food.css' />\
</head>"
html += "<html><body><h3>Food Recipes (as of [time2text(world.realtime,"MMM DD, YYYY")])</h3><br>"
html += "<table class='recipes'>"
html += "<tr><th>Icon</th><th>Name</th><th>Ingredients</th></tr>"
for(var/Rp in food_recipes)
//Open this row
html += "<tr>"
//Image
var/icon/icon_to_give = food_recipes[Rp]["Image"]
if(icon_to_give)
var/image_path = "recipe-[ckey(food_recipes[Rp]["Result"])].png"
html += "<td><img src='imgrecipes/[image_path]' /></td>"
src << browse(icon_to_give, "window=picture;file=[image_path];display=0")
else
html += "<td>No<br>Image</td>"
//Name
html += "<td><b>[food_recipes[Rp]["Result"]]</b></td>"
//Ingredients
html += "<td><ul>"
var/count //For those commas. Not sure of a great other way to do it.
//For each large ingredient
var/pretty_ing = ""
count = 0
for(var/ing in food_recipes[Rp]["Ingredients"])
pretty_ing += "[count == 0 ? "" : ", "][food_recipes[Rp]["Ingredients"][ing]]x [ing]"
count++
if(pretty_ing != "")
html += "<li><b>Ingredients:</b> [pretty_ing]</li>"
//For each fruit
var/pretty_fru = ""
count = 0
for(var/fru in food_recipes[Rp]["Fruit"])
pretty_fru += "[count == 0 ? "" : ", "][food_recipes[Rp]["Fruit"][fru]]x [fru]"
count++
if(pretty_fru != "")
html += "<li><b>Fruit:</b> [pretty_fru]</li>"
//For each reagent
var/pretty_rea = ""
count = 0
for(var/rea in food_recipes[Rp]["Reagents"])
pretty_rea += "[count == 0 ? "" : ", "][food_recipes[Rp]["Reagents"][rea]]u [rea]"
count++
if(pretty_rea != "")
html += "<li><b>Mix in:</b> [pretty_rea]</li>"
//Close ingredients
html += "</ul></td>"
//Close this row
html += "</tr>"
html += "</table></body></html>"
src << browse(html, "window=recipes;file=recipes_food.html;display=0")
//Drink Output
html = "<head>\
<meta charset='utf-8'>\
<meta http-equiv='X-UA-Compatible' content='IE=edge'>\
<meta http-equiv='content-language' content='en-us' />\
<meta name='viewport' content='width=device-width, initial-scale=1'>\
<title>Drink Recipes</title>\
<link rel='stylesheet' href='drinks.css' />\
</head>"
html += "<html><body><h3>Drink Recipes (as of [time2text(world.realtime,"MMM DD, YYYY")])</h3><br>"
html += "<table class='recipes'>"
html += "<tr><th>Name</th><th>Ingredients</th></tr>"
for(var/Rp in drink_recipes)
//Open this row
html += "<tr>"
//Name
html += "<td><b>[drink_recipes[Rp]["Result"]]</b></td>"
html += "<td>"
//For each reagent
var/pretty_rea = ""
var/count = 0
for(var/rea in drink_recipes[Rp]["Reagents"])
pretty_rea += "[count == 0 ? "" : ", "][drink_recipes[Rp]["Reagents"][rea]]u [rea]"
count++
if(pretty_rea != "")
html += "<li><b>Mix together:</b> [pretty_rea]</li>"
html += "<li>Makes [drink_recipes[Rp]["ResAmt"]]u</li>"
//Close reagents
html += "</ul></td>"
//Close this row
html += "</tr>"
html += "</table></body></html>"
src << browse(html, "window=recipes;file=recipes_drinks.html;display=0")
src << "<span class='notice'>In your byond cache, recipe-xxx.png files and recipes_drinks.html and recipes_food.html now exist. Place recipe-xxx.png files in a subfolder named 'imgrecipes' wherever you put them. The file will take a food.css or drinks.css file if in the same path.</span>"
+12 -12
View File
@@ -621,8 +621,8 @@ I said no!
/datum/recipe/sandwich
items = list(
/obj/item/weapon/reagent_containers/food/snacks/meatsteak,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/cheesewedge,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sandwich
@@ -635,8 +635,8 @@ I said no!
/datum/recipe/grilledcheese
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/cheesewedge,
)
result = /obj/item/weapon/reagent_containers/food/snacks/grilledcheese
@@ -663,14 +663,14 @@ I said no!
/datum/recipe/slimetoast
reagents = list("slimejelly" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime
/datum/recipe/jelliedtoast
reagents = list("cherryjelly" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry
@@ -783,24 +783,24 @@ I said no!
/datum/recipe/twobread
reagents = list("wine" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/twobread
/datum/recipe/slimesandwich
reagents = list("slimejelly" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime
/datum/recipe/cherrysandwich
reagents = list("cherryjelly" = 5)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
/obj/item/weapon/reagent_containers/food/snacks/slice/bread,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry
@@ -0,0 +1,24 @@
//
// This event chooses a random canister on player levels and breaks it, releasing its contents!
//
/datum/gm_action/canister_leak
name = "Canister Leak"
departments = list(ROLE_ENGINEERING)
chaotic = 20
/datum/gm_action/canister_leak/get_weight()
return metric.count_people_in_department(ROLE_ENGINEERING) * 30
/datum/gm_action/canister_leak/start()
..()
// List of all non-destroyed canisters on station levels
var/list/all_canisters = list()
for(var/obj/machinery/portable_atmospherics/canister/C in machines)
if(!C.destroyed && (C.z in using_map.station_levels) && C.air_contents.total_moles >= MOLES_CELLSTANDARD)
all_canisters += C
var/obj/machinery/portable_atmospherics/canister/C = pick(all_canisters)
log_debug("canister_leak event: Canister [C] ([C.x],[C.y],[C.z]) destroyed.")
C.health = 0
C.healthcheck()
return
+1 -1
View File
@@ -184,7 +184,7 @@
display_name = "killer tomato plant"
mutants = null
can_self_harvest = 1
has_mob_product = /mob/living/simple_animal/tomato
has_mob_product = /mob/living/simple_animal/hostile/tomato
/datum/seed/tomato/killer/New()
..()
@@ -71,6 +71,8 @@
new/datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("voidcraft airlock assembly horizontal", /obj/structure/door_assembly/door_assembly_voidcraft, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("voidcraft airlock assembly vertical", /obj/structure/door_assembly/door_assembly_voidcraft/vertical, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("emergency shutter", /obj/structure/firedoor_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("multi-tile airlock assembly", /obj/structure/door_assembly/multi_tile, 4, time = 50, one_per_turf = 1, on_floor = 1), \
))
+7 -1
View File
@@ -597,7 +597,7 @@ var/list/name_to_material
stack_type = /obj/item/stack/material/wood
icon_colour = "#824B28"
integrity = 50
icon_base = "solid"
icon_base = "wood"
explosion_resistance = 2
shard_type = SHARD_SPLINTER
shard_can_repair = 0 // you can't weld splinters back into planks
@@ -618,6 +618,12 @@ var/list/name_to_material
stack_type = null
shard_type = SHARD_NONE
/material/wood/sif
name = "alien wood"
// stack_type = /obj/item/stack/material/wood/sif
icon_colour = "#0099cc" // Cyan-ish
stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) // Alien wood would presumably be more interesting to the analyzer.
/material/cardboard
name = "cardboard"
stack_type = /obj/item/stack/material/cardboard
+4
View File
@@ -23,6 +23,8 @@
if (message)
log_emote("[name]/[key] : [message]")
message = say_emphasis(message)
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
@@ -63,6 +65,8 @@
else
input = message
input = say_emphasis(input)
if(input)
log_emote("Ghost/[src.key] : [input]")
if(!invisibility) //If the ghost is made visible by admins or cult. And to see if the ghost has toggled its own visibility, as well. -Mech
+82 -15
View File
@@ -32,14 +32,10 @@
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
message = pick(S.speak)
if(language)
message = language.scramble(message)
else
if(language)
message = language.scramble(message)
else
message = stars(message)
message = stars(message)
var/speaker_name = speaker.name
if(istype(speaker, /mob/living/carbon/human))
@@ -49,6 +45,8 @@
if(italics)
message = "<i>[message]</i>"
message = say_emphasis(message)
var/track = null
if(istype(src, /mob/observer/dead))
if(italics && is_preference_enabled(/datum/client_preference/ghost_radio))
@@ -66,20 +64,73 @@
else
src << "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear."
else
var/message_to_send = null
if(language)
on_hear_say("<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>")
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>"
else
on_hear_say("<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>")
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>"
if(check_mentioned(message) && is_preference_enabled(/datum/client_preference/check_mention))
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
on_hear_say(message_to_send)
if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
src.playsound_local(source, speech_sound, sound_vol, 1)
/mob/proc/on_hear_say(var/message)
src << message
to_chat(src, message)
/mob/living/silicon/on_hear_say(var/message)
var/time = say_timestamp()
src << "[time] [message]"
to_chat(src, "[time] [message]")
// Checks if the mob's own name is included inside message. Handles both first and last names.
/mob/proc/check_mentioned(var/message)
var/list/valid_names = splittext(real_name, " ") // Should output list("John", "Doe") as an example.
valid_names += special_mentions()
for(var/name in valid_names)
if(findtext(message, regex("\\b[name]\\b", "i"))) // This is to stop 'ai' from triggering if someone says 'wait'.
return TRUE
return FALSE
// Override this if you want something besides the mob's name to count for being mentioned in check_mentioned().
/mob/proc/special_mentions()
return list()
/mob/living/silicon/ai/special_mentions()
return list("AI") // AI door!
// Converts specific characters, like *, /, and _ to formatted output.
/mob/proc/say_emphasis(var/message)
message = encode_html_emphasis(message, "/", "i")
message = encode_html_emphasis(message, "+", "b")
message = encode_html_emphasis(message, "_", "u")
return message
// Replaces a character inside message with html tags. Note that html var must not include brackets.
// Will not create an open html tag if it would not have a closing one.
/proc/encode_html_emphasis(var/message, var/char, var/html)
var/i = 20 // Infinite loop safety.
var/pattern = "(?<!<)\\" + char
var/regex/re = regex(pattern,"i") // This matches results which do not have a < next to them, to avoid stripping slashes from closing html tags.
var/first = re.Find(message) // Find first occurance.
var/second = re.Find(message, first + 1) // Then the second.
while(first && second && i)
// Calculate how far foward the second char is, as the first replacetext() will displace it.
var/length_increase = length("<[html]>") - 1
// Now replace both.
message = replacetext(message, char, "<[html]>", first, first + 1)
message = replacetext(message, char, "</[html]>", second + length_increase, second + length_increase + 1)
// Check again to see if we need to keep going.
first = re.Find(message)
second = re.Find(message, first + 1)
i--
if(!i)
CRASH("Possible infinite loop occured in encode_html_emphasis().")
return message
/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
@@ -182,11 +233,15 @@
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
message = say_emphasis(message)
var/formatted
if(language)
formatted = "[language.format_message_radio(message, verb)][part_c]"
else
formatted = "[verb], <span class=\"body\">\"[message]\"</span>[part_c]"
if((sdisabilities & DEAF) || ear_deaf)
if(prob(20))
src << "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>"
@@ -197,18 +252,30 @@
return "<span class='say_quote'>\[[stationtime2text()]\]</span>"
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
src << "[part_a][speaker_name][part_b][formatted]"
var/final_message = "[part_a][speaker_name][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/observer/dead/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
src << "[part_a][track][part_b][formatted]"
var/final_message = "[part_a][track][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp()
src << "[time][part_a][speaker_name][part_b][formatted]"
var/final_message = "[part_a][speaker_name][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "[time]<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp()
src << "[time][part_a][track][part_b][formatted]"
var/final_message = "[part_a][track][part_b][formatted]"
if(check_mentioned(formatted) && is_preference_enabled(/datum/client_preference/check_mention))
final_message = "[time]<font size='3'><b>[final_message]</b></font>"
to_chat(src, final_message)
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
+10 -3
View File
@@ -17,15 +17,19 @@
if (!message)
return
message = speaker.say_emphasis(message)
var/message_start = "<i><span class='game say'>[name], <span class='name'>[speaker.name]</span>"
var/message_body = "<span class='message'>[speaker.say_quote(message)], \"[message]\"</span></span></i>"
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
M.show_message("[message_start] ([ghost_follow_link(speaker, M)]) [message_body]", 2)
var/message_to_send = "[message_start] ([ghost_follow_link(speaker, M)]) [message_body]"
if(M.check_mentioned(message) && M.is_preference_enabled(/datum/client_preference/check_mention))
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
M.show_message(message_to_send, 2)
for (var/mob/living/S in living_mob_list)
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
continue
else if(istype(S , /mob/living/silicon/ai))
@@ -33,7 +37,10 @@
else if (!S.binarycheck())
continue
S.show_message("[message_start] [message_body]", 2)
var/message_to_send = "[message_start] [message_body]"
if(S.check_mentioned(message) && S.is_preference_enabled(/datum/client_preference/check_mention))
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
S.show_message(message_to_send, 2)
var/list/listening = hearers(1, src)
listening -= src
+2
View File
@@ -59,6 +59,8 @@
/datum/species/proc/handle_autohiss(message, datum/language/lang, mode)
if(!autohiss_basic_map)
return message
if(lang.flags & NO_STUTTER) // Currently prevents EAL, Sign language, and emotes from autohissing
return message
if(autohiss_exempt && (lang.name in autohiss_exempt))
return message
+39 -11
View File
@@ -27,7 +27,7 @@
var/turf/obstacle = null
var/wait_if_pulled = 0 // Only applies to moving to the target
var/will_patrol = 0 // Not a setting - whether or no this type of bots patrols at all
var/will_patrol = 0 // If set to 1, will patrol, duh
var/patrol_speed = 1 // How many times per tick we move when patrolling
var/target_speed = 2 // Ditto for chasing the target
var/min_target_dist = 1 // How close we try to get to the target
@@ -49,7 +49,11 @@
access_scanner.req_access = req_access.Copy()
access_scanner.req_one_access = req_one_access.Copy()
turn_on()
// Make sure mapped in units start turned on.
/mob/living/bot/initialize()
..()
if(on)
turn_on() // Update lights and other stuff
/mob/living/bot/Life()
..()
@@ -61,7 +65,8 @@
paralysis = 0
if(on && !client && !busy)
handleAI()
spawn(0)
handleAI()
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
@@ -145,20 +150,18 @@
handleRangedTarget()
if(!wait_if_pulled || !pulledby)
for(var/i = 1 to target_speed)
sleep(20 / (target_speed + 1))
stepToTarget()
if(i < target_speed)
sleep(20 / target_speed)
if(max_frustration && frustration > max_frustration * target_speed)
handleFrustrated(1)
else
resetTarget()
lookForTargets()
if(will_patrol && !pulledby && !target)
if(patrol_path.len)
if(patrol_path && patrol_path.len)
for(var/i = 1 to patrol_speed)
sleep(20 / (patrol_speed + 1))
handlePatrol()
if(i < patrol_speed)
sleep(20 / patrol_speed)
if(max_frustration && frustration > max_frustration * patrol_speed)
handleFrustrated(0)
else
@@ -219,6 +222,25 @@
return
/mob/living/bot/proc/getPatrolTurf()
var/minDist = INFINITY
var/obj/machinery/navbeacon/targ = locate() in get_turf(src)
if(!targ)
for(var/obj/machinery/navbeacon/N in navbeacons)
if(!N.codes["patrol"])
continue
if(get_dist(src, N) < minDist)
minDist = get_dist(src, N)
targ = N
if(targ && targ.codes["next_patrol"])
for(var/obj/machinery/navbeacon/N in navbeacons)
if(N.location == targ.codes["next_patrol"])
targ = N
break
if(targ)
return get_turf(targ)
return null
/mob/living/bot/proc/handleIdle()
@@ -255,15 +277,16 @@
on = 1
set_light(light_strength)
update_icons()
resetTarget()
patrol_path = list()
ignore_list = list()
return 1
/mob/living/bot/proc/turn_off()
on = 0
busy = 0 // If ever stuck... reboot!
set_light(0)
update_icons()
resetTarget()
patrol_path = list()
ignore_list = list()
/mob/living/bot/proc/explode()
qdel(src)
@@ -327,6 +350,11 @@
for(var/obj/machinery/door/D in loc)
if(!D.density) continue
if(istype(D, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/A = D
if(!A.can_open()) return 1
if(istype(D, /obj/machinery/door/window))
if( dir & D.dir ) return !D.check_access(ID)
+6 -5
View File
@@ -12,7 +12,6 @@
var/cleaning = 0
var/screwloose = 0
var/oddbutton = 0
var/should_patrol = 0
var/blood = 1
var/list/target_types = list()
@@ -32,9 +31,11 @@
if(oddbutton && prob(5)) // Make a big mess
visible_message("Something flies out of [src]. He seems to be acting oddly.")
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc)
ignore_list += gib
// TODO - I have a feeling weakrefs will not work in ignore_list, verify this ~Leshana
var/weakref/g = weakref(gib)
ignore_list += g
spawn(600)
ignore_list -= gib
ignore_list -= g
/mob/living/bot/cleanbot/lookForTargets()
for(var/obj/effect/decal/cleanable/D in view(world.view, src)) // There was some odd code to make it start with nearest decals, it's unnecessary, this works
@@ -110,7 +111,7 @@
dat += "Maintenance panel is [open ? "opened" : "closed"]"
if(!locked || issilicon(user))
dat += "<BR>Cleans Blood: <A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A><BR>"
dat += "<BR>Patrol station: <A href='?src=\ref[src];operation=patrol'>[should_patrol ? "Yes" : "No"]</A><BR>"
dat += "<BR>Patrol station: <A href='?src=\ref[src];operation=patrol'>[will_patrol ? "Yes" : "No"]</A><BR>"
if(open && !locked)
dat += "Odd looking screw twiddled: <A href='?src=\ref[src];operation=screw'>[screwloose ? "Yes" : "No"]</A><BR>"
dat += "Weird button pressed: <A href='?src=\ref[src];operation=oddbutton'>[oddbutton ? "Yes" : "No"]</A>"
@@ -134,7 +135,7 @@
blood = !blood
get_targets()
if("patrol")
should_patrol = !should_patrol
will_patrol = !will_patrol
patrol_path = null
if("screw")
screwloose = !screwloose
+3 -3
View File
@@ -170,7 +170,7 @@
visible_message("<span class='notice'>[src] starts [T.dead? "removing the plant from" : "harvesting"] \the [A].</span>")
busy = 1
if(do_after(src, 30))
if(do_after(src, 30, A))
visible_message("<span class='notice'>[src] [T.dead? "removes the plant from" : "harvests"] \the [A].</span>")
T.attack_hand(src)
if(FARMBOT_WATER)
@@ -179,7 +179,7 @@
visible_message("<span class='notice'>[src] starts watering \the [A].</span>")
busy = 1
if(do_after(src, 30))
if(do_after(src, 30, A))
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
visible_message("<span class='notice'>[src] waters \the [A].</span>")
tank.reagents.trans_to(T, 100 - T.waterlevel)
@@ -198,7 +198,7 @@
visible_message("<span class='notice'>[src] starts fertilizing \the [A].</span>")
busy = 1
if(do_after(src, 30))
if(do_after(src, 30, A))
visible_message("<span class='notice'>[src] fertilizes \the [A].</span>")
T.reagents.add_reagent("ammonia", 10)
+53 -30
View File
@@ -1,3 +1,9 @@
// Configure whether or not floorbot will fix hull breaches.
// This can be a problem if it tries to pave over space or shuttles. That should be fixed but...
// If it can see space outside windows, it can be laggy since it keeps wondering if it should fix them.
// Therefore that functionality is disabled for now. But it can be turned on by uncommenting this.
// #define FLOORBOT_PATCHES_HOLES 1
/mob/living/bot/floorbot
name = "Floorbot"
desc = "A little floor repairing robot, he looks so excited!"
@@ -25,7 +31,7 @@
/mob/living/bot/floorbot/attack_hand(var/mob/user)
user.set_machine(src)
var/dat
var/list/dat = list()
dat += "<TT><B>Automatic Station Floor Repairer v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];operation=start'>[src.on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel is [open ? "opened" : "closed"]<BR>"
@@ -41,9 +47,9 @@
else
bmode = "Disabled"
dat += "<BR><BR>Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
user << browse("<HEAD><TITLE>Repairbot v1.0 controls</TITLE></HEAD>[dat]", "window=autorepair")
onclose(user, "autorepair")
var/datum/browser/popup = new(user, "autorepair", "Repairbot v1.1 controls")
popup.set_content(jointext(dat,null))
popup.open()
return
/mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user)
@@ -115,23 +121,24 @@
target = T
return
T = get_step(T, targetdirection)
return // In bridge mode we don't want to step off that line even to eat plates!
else // Fixing floors
for(var/turf/space/T in view(src)) // Breaches are of higher priority
if(confirmTarget(T))
target = T
return
#ifdef FLOORBOT_PATCHES_HOLES
for(var/turf/space/T in view(src)) // Breaches are of higher priority
if(confirmTarget(T))
target = T
return
for(var/turf/simulated/mineral/floor/T in view(src)) // Asteroids are of smaller priority
if(confirmTarget(T))
target = T
return
if(improvefloors)
for(var/turf/simulated/floor/T in view(src))
if(confirmTarget(T))
target = T
return
for(var/turf/simulated/mineral/floor/T in view(src)) // Asteroids are of smaller priority
if(confirmTarget(T))
target = T
return
#endif
// Look for broken floors even if we aren't improvefloors
for(var/turf/simulated/floor/T in view(src))
if(confirmTarget(T))
target = T
return
if(amount < maxAmount && (eattiles || maketiles))
for(var/obj/item/stack/S in view(src))
@@ -148,7 +155,11 @@
if(istype(A, /obj/item/stack/material/steel))
return (amount < maxAmount && maketiles)
if(A.loc.name == "Space")
// Don't pave over all of space, build there only if in bridge mode
if(!targetdirection && istype(A.loc, /area/space)) // Note name == "Space" does not work!
return 0
if(istype(A.loc, /area/shuttle)) // Do NOT mess with shuttle drop zones
return 0
if(emagged)
@@ -157,14 +168,16 @@
if(!amount)
return 0
#ifdef FLOORBOT_PATCHES_HOLES
if(istype(A, /turf/space))
return 1
if(istype(A, /turf/simulated/mineral/floor))
return 1
#endif
var/turf/simulated/floor/T = A
return (istype(T) && improvefloors && !T.flooring && (get_turf(T) == loc || prob(40)))
return (istype(T) && (T.broken || T.burnt || (improvefloors && !T.flooring)) && (get_turf(T) == loc || prob(40)))
/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity)
if(!..())
@@ -181,12 +194,12 @@
busy = 1
update_icons()
if(F.flooring)
visible_message("<span class='warning'>[src] begins to tear the floor tile from the floor!</span>")
visible_message("<span class='warning'>\The [src] begins to tear the floor tile from the floor!</span>")
if(do_after(src, 50))
F.break_tile_to_plating()
addTiles(1)
else
visible_message("<span class='danger'>[src] begins to tear through the floor!</span>")
visible_message("<span class='danger'>\The [src] begins to tear through the floor!</span>")
if(do_after(src, 150)) // Extra time because this can and will kill.
F.ReplaceWithLattice()
addTiles(1)
@@ -201,7 +214,7 @@
return
busy = 1
update_icons()
visible_message("<span class='notice'>[src] begins to repair the hole.</span>")
visible_message("<span class='notice'>\The [src] begins to repair the hole.</span>")
if(do_after(src, 50))
if(A && (locate(/obj/structure/lattice, A) && building == 1 || !locate(/obj/structure/lattice, A) && building == 2)) // Make sure that it still needs repairs
var/obj/item/I
@@ -215,10 +228,20 @@
update_icons()
else if(istype(A, /turf/simulated/floor))
var/turf/simulated/floor/F = A
if(!F.flooring && amount)
if(F.broken || F.burnt)
busy = 1
update_icons()
visible_message("<span class='notice'>[src] begins to improve the floor.</span>")
visible_message("<span class='notice'>\The [src] begins to remove the broken floor.</span>")
if(do_after(src, 50, F))
if(F.broken || F.burnt)
F.make_plating()
target = null
busy = 0
update_icons()
else if(!F.flooring && amount)
busy = 1
update_icons()
visible_message("<span class='notice'>\The [src] begins to improve the floor.</span>")
if(do_after(src, 50))
if(!F.flooring)
F.set_flooring(get_flooring_data(floor_build_type))
@@ -228,7 +251,7 @@
update_icons()
else if(istype(A, /obj/item/stack/tile/floor) && amount < maxAmount)
var/obj/item/stack/tile/floor/T = A
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
visible_message("<span class='notice'>\The [src] begins to collect tiles.</span>")
busy = 1
update_icons()
if(do_after(src, 20))
@@ -242,7 +265,7 @@
else if(istype(A, /obj/item/stack/material) && amount + 4 <= maxAmount)
var/obj/item/stack/material/M = A
if(M.get_material_name() == DEFAULT_WALL_MATERIAL)
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
visible_message("<span class='notice'>\The [src] begins to make tiles.</span>")
busy = 1
update_icons()
if(do_after(50))
@@ -252,7 +275,7 @@
/mob/living/bot/floorbot/explode()
turn_off()
visible_message("<span class='danger'>[src] blows apart!</span>")
visible_message("<span class='danger'>\The [src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec)
@@ -353,4 +376,4 @@
return
if(!in_range(src, user) && loc != user)
return
created_name = t
created_name = t
+15 -12
View File
@@ -130,10 +130,7 @@
if("sethome")
var/new_dest
var/list/beaconlist = new()
for(var/obj/machinery/navbeacon/N in navbeacons)
beaconlist.Add(N.location)
beaconlist[N.location] = N
var/list/beaconlist = GetBeaconList()
if(beaconlist.len)
new_dest = input("Select new home tag", "Mulebot [suffix ? "([suffix])" : ""]", null) in null|beaconlist
else
@@ -168,10 +165,7 @@
targetName = "Home"
if("SetD")
var/new_dest
var/list/beaconlist = new()
for(var/obj/machinery/navbeacon/N in navbeacons)
beaconlist.Add(N.location)
beaconlist[N.location] = N
var/list/beaconlist = GetBeaconList()
if(beaconlist.len)
new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]") in null|beaconlist
else
@@ -285,6 +279,15 @@
new /obj/effect/decal/cleanable/blood/oil(Tsec)
..()
/mob/living/bot/mulebot/proc/GetBeaconList()
var/list/beaconlist = list()
for(var/obj/machinery/navbeacon/N in navbeacons)
if(!N.codes["delivery"])
continue
beaconlist.Add(N.location)
beaconlist[N.location] = N
return beaconlist
/mob/living/bot/mulebot/proc/load(var/atom/movable/C)
if(busy || load || get_dist(C, src) > 1 || !isturf(C.loc))
return
@@ -304,11 +307,11 @@
busy = 1
C.loc = loc
C.forceMove(loc)
sleep(2)
if(C.loc != loc) //To prevent you from going onto more than one bot.
return
C.loc = src
C.forceMove(src)
load = C
C.pixel_y += 9
@@ -325,7 +328,7 @@
busy = 1
overlays.Cut()
load.loc = loc
load.forceMove(loc)
load.pixel_y -= 9
load.layer = initial(load.layer)
@@ -338,7 +341,7 @@
if(AM == botcard || AM == access_scanner)
continue
AM.loc = loc
AM.forceMove(loc)
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
busy = 0
+73 -36
View File
@@ -1,10 +1,14 @@
#define SECBOT_WAIT_TIME 5 //number of in-game seconds to wait for someone to surrender
#define SECBOT_THREAT_ARREST 4 //threat level at which we decide to arrest someone
#define SECBOT_THREAT_ATTACK 8 //threat level at which was assume immediate danger and attack right away
/mob/living/bot/secbot
name = "Securitron"
desc = "A little security robot. He looks less than thrilled."
icon_state = "secbot0"
maxHealth = 100
health = 100
req_one_access = list(access_robotics, access_security, access_forensics_lockers)
req_one_access = list(access_security, access_forensics_lockers)
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
patrol_speed = 2
target_speed = 3
@@ -14,18 +18,17 @@
var/check_arrest = 1 // If true, arrests people who are set to arrest.
var/arrest_type = 0 // If true, doesn't handcuff. You monster.
var/declare_arrests = 0 // If true, announces arrests over sechuds.
var/auto_patrol = 0 // If true, patrols on its own
var/is_ranged = 0
var/awaiting_surrender = 0
var/list/threat_found_sounds = new('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg')
var/list/preparing_arrest_sounds = new('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg')
var/list/threat_found_sounds = list('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg')
var/list/preparing_arrest_sounds = list('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/bcreep.ogg')
/mob/living/bot/secbot/beepsky
name = "Officer Beepsky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
auto_patrol = 1
will_patrol = 1
/mob/living/bot/secbot/update_icons()
if(on && busy)
@@ -40,7 +43,7 @@
/mob/living/bot/secbot/attack_hand(var/mob/user)
user.set_machine(src)
var/dat
var/list/dat = list()
dat += "<TT><B>Automatic Security Unit</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
@@ -51,10 +54,10 @@
dat += "Check Arrest Status: <A href='?src=\ref[src];operation=ignorearr'>[check_arrest ? "Yes" : "No"]</A><BR>"
dat += "Operating Mode: <A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A><BR>"
dat += "Report Arrests: <A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A><BR>"
dat += "Auto Patrol: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>"
user << browse("<HEAD><TITLE>Securitron controls</TITLE></HEAD>[dat]", "window=autosec")
onclose(user, "autosec")
return
dat += "Auto Patrol: <A href='?src=\ref[src];operation=patrol'>[will_patrol ? "On" : "Off"]</A>"
var/datum/browser/popup = new(user, "autosec", "Securitron controls")
popup.set_content(jointext(dat,null))
popup.open()
/mob/living/bot/secbot/Topic(href, href_list)
if(..())
@@ -80,7 +83,7 @@
if("switchmode")
arrest_type = !arrest_type
if("patrol")
auto_patrol = !auto_patrol
will_patrol = !will_patrol
if("declarearrests")
declare_arrests = !declare_arrests
attack_hand(usr)
@@ -99,10 +102,46 @@
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
var/curhealth = health
..()
. = ..()
if(health < curhealth)
target = user
awaiting_surrender = 5
react_to_attack(user)
/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P)
var/curhealth = health
var/mob/shooter = P.firer
. = ..()
//if we already have a target just ignore to avoid lots of checking
if(!target && health < curhealth && shooter && (shooter in view(world.view, src)))
react_to_attack(shooter)
/mob/living/bot/secbot/proc/react_to_attack(mob/attacker)
if(!target)
playsound(src.loc, pick(threat_found_sounds), 50)
broadcast_security_hud_message("[src] was attacked by a hostile <b>[target_name(attacker)]</b> in <b>[get_area(src)]</b>.", src)
target = attacker
awaiting_surrender = INFINITY // Don't try and wait for surrender
// Say "freeze!" and demand surrender
/mob/living/bot/secbot/proc/demand_surrender(mob/target, var/threat)
var/suspect_name = target_name(target)
if(declare_arrests)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [threat] suspect <b>[suspect_name]</b> in <b>[get_area(src)]</b>.", src)
say("Down on the floor, [suspect_name]! You have [SECBOT_WAIT_TIME] seconds to comply.")
playsound(src.loc, pick(preparing_arrest_sounds), 50)
// Register to be told when the target moves
moved_event.register(target, src, /mob/living/bot/secbot/proc/target_moved)
// Callback invoked if the registered target moves
/mob/living/bot/secbot/proc/target_moved(atom/movable/moving_instance, atom/old_loc, atom/new_loc)
if(get_dist(get_turf(src), get_turf(target)) >= 1)
awaiting_surrender = INFINITY // Done waiting!
moved_event.unregister(moving_instance, src)
/mob/living/bot/secbot/resetTarget()
..()
moved_event.unregister(target, src)
awaiting_surrender = -1
walk_to(src, 0)
/mob/living/bot/secbot/startPatrol()
if(!locked) // Stop running away when we set you up
@@ -112,8 +151,7 @@
/mob/living/bot/secbot/confirmTarget(var/atom/A)
if(!..())
return 0
return (check_threat(A) > 3)
return (check_threat(A) >= SECBOT_THREAT_ARREST)
/mob/living/bot/secbot/lookForTargets()
for(var/mob/living/M in view(src))
@@ -127,23 +165,17 @@
custom_emote(1, "points at [M.name]!")
return
/mob/living/bot/secbot/calcTargetPath()
..()
if(awaiting_surrender != -1)
awaiting_surrender = 5 // This implies that a) we have already approached the target and b) it has moved after the warning
/mob/living/bot/secbot/handleAdjacentTarget()
if(awaiting_surrender < 5 && ishuman(target) && !target:lying)
if(awaiting_surrender == -1)
say("Down on the floor, [target]! You have five seconds to comply.")
var/mob/living/carbon/human/H = target
var/threat = check_threat(target)
if(awaiting_surrender < SECBOT_WAIT_TIME && istype(H) && !H.lying && threat < SECBOT_THREAT_ATTACK)
if(awaiting_surrender == -1) // On first tick of awaiting...
demand_surrender(target, threat)
++awaiting_surrender
else
if(declare_arrests)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [threat] suspect <b>[target_name(target)]</b> in <b>[get_area(src)]</b>.", src)
UnarmedAttack(target)
if(ishuman(target) && declare_arrests)
var/area/location = get_area(src)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect <b>[target]</b> in <b>[location]</b>.", src)
// say("Engaging patrol mode.")
/mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity)
if(!..())
@@ -170,17 +202,15 @@
spawn(2)
busy = 0
update_icons()
visible_message("<span class='warning'>[C] was prodded by [src] with a stun baton!</span>")
visible_message("<span class='warning'>\The [C] was prodded by \the [src] with a stun baton!</span>")
else
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
visible_message("<span class='warning'>[src] is trying to put handcuffs on [C]!</span>")
visible_message("<span class='warning'>\The [src] is trying to put handcuffs on \the [C]!</span>")
busy = 1
if(do_mob(src, C, 60))
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/handcuffs(C)
C.update_inv_handcuffed()
if(preparing_arrest_sounds.len)
playsound(loc, pick(preparing_arrest_sounds), 50, 0)
busy = 0
else if(istype(M, /mob/living/simple_animal))
var/mob/living/simple_animal/S = M
@@ -193,7 +223,8 @@
spawn(2)
busy = 0
update_icons()
visible_message("<span class='warning'>[M] was beaten by [src] with a stun baton!</span>")
visible_message("<span class='warning'>\The [M] was beaten by \the [src] with a stun baton!</span>")
/mob/living/bot/secbot/explode()
visible_message("<span class='warning'>[src] blows apart!</span>")
@@ -215,11 +246,17 @@
new /obj/effect/decal/cleanable/blood/oil(Tsec)
qdel(src)
/mob/living/bot/secbot/proc/target_name(mob/living/T)
if(ishuman(T))
var/mob/living/carbon/human/H = T
return H.get_id_name("unidentified person")
return "unidentified lifeform"
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(!M || !istype(M) || M.stat == DEAD || src == M)
return 0
if(emagged)
if(emagged && !M.incapacitated()) //check incapacitated so emagged secbots don't keep attacking the same target forever
return 10
return M.assess_perp(access_scanner, 0, idcheck, check_records, check_arrest)
@@ -297,4 +334,4 @@
return
if(!in_range(src, usr) && loc != usr)
return
created_name = t
created_name = t
+6 -2
View File
@@ -164,7 +164,9 @@
if(2)
brainmob.emp_damage += rand(10,20)
if(3)
brainmob.emp_damage += rand(0,10)
brainmob.emp_damage += rand(5,10)
if(4)
brainmob.emp_damage += rand(0,5)
..()
/obj/item/device/mmi/digital
@@ -216,7 +218,9 @@
if(2)
src.brainmob.emp_damage += rand(10,20)
if(3)
src.brainmob.emp_damage += rand(0,10)
src.brainmob.emp_damage += rand(5,10)
if(4)
src.brainmob.emp_damage += rand(0,5)
..()
/obj/item/device/mmi/digital/transfer_identity(var/mob/living/carbon/H)
@@ -112,7 +112,9 @@
if(2)
src.brainmob.emp_damage += rand(10,20)
if(3)
src.brainmob.emp_damage += rand(0,10)
src.brainmob.emp_damage += rand(5,10)
if(4)
src.brainmob.emp_damage += rand(0,5)
..()
/obj/item/device/mmi/digital/posibrain/New()
+89 -18
View File
@@ -25,7 +25,8 @@
message = "is strumming the air and headbanging like a safari chimp."
m_type = 1
if("ping", "beep", "buzz", "yes", "no")
//Machine-only emotes
if("ping", "beep", "buzz", "yes", "no", "rcough", "rsneeze")
if(!isSynthetic())
src << "<span class='warning'>You are not a synthetic.</span>"
@@ -54,6 +55,18 @@
else if(act == "no")
display_msg = "emits a negative blip"
use_sound = 'sound/machines/synth_no.ogg'
else if(act == "rcough")
display_msg = "emits a robotic cough"
if(gender == FEMALE)
use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg')
else
use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg')
else if(act == "rsneeze")
display_msg = "emits a robotic sneeze"
if(gender == FEMALE)
use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg'
else
use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
if (param)
message = "[display_msg] at [param]."
@@ -62,6 +75,17 @@
playsound(src.loc, use_sound, 50, 0)
m_type = 1
//Promethean-only emotes
if("squish")
if(!species.bump_flag == SLIME) //That should do, yaya.
src << "<span class='warning'>You are not a slime thing!</span>"
return
playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
message = "blinks."
m_type = 1
if ("blink")
message = "blinks."
m_type = 1
@@ -202,14 +226,20 @@
src.sleeping += 10 //Short-short nap
m_type = 1
if ("cough")
if("cough", "coughs")
if(miming)
message = "appears to cough!"
m_type = 1
else
if (!muzzled)
if(!muzzled)
message = "coughs!"
m_type = 2
if(gender == FEMALE)
if(species.female_cough_sounds)
playsound(src, pick(species.female_cough_sounds), 120)
else
if(species.male_cough_sounds)
playsound(src, pick(species.male_cough_sounds), 120)
else
message = "makes a strong noise."
m_type = 2
@@ -456,13 +486,17 @@
message = "trembles in fear!"
m_type = 1
if ("sneeze")
if (miming)
if("sneeze", "sneezes")
if(miming)
message = "sneezes."
m_type = 1
else
if (!muzzled)
if(!muzzled)
message = "sneezes."
if(gender == FEMALE)
playsound(src, species.female_sneeze_sound, 70)
else
playsound(src, species.male_sneeze_sound, 70)
m_type = 2
else
message = "makes a strange noise."
@@ -565,18 +599,59 @@
else
message = "sadly can't find anybody to give daps to, and daps [get_visible_gender() == MALE ? "himself" : get_visible_gender() == FEMALE ? "herself" : "themselves"]. Shameful."
if ("scream")
if (miming)
if("slap", "slaps")
m_type = 1
if(!restrained())
var/M = null
if(param)
for(var/mob/A in view(1, null))
if(param == A.name)
M = A
break
if(M)
message = "<span class='danger'>slaps [M] across the face. Ouch!</span>"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
else
message = "<span class='danger'>slaps [get_visible_gender() == MALE ? "himself" : get_visible_gender() == FEMALE ? "herself" : "themselves"]!</span>"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
if("scream", "screams")
if(miming)
message = "acts out a scream!"
m_type = 1
else
if (!muzzled)
message = "screams!"
if(!muzzled)
message = "[species.scream_verb]!"
m_type = 2
/* Removed, pending the location of some actually good, properly licensed sounds.
if(gender == FEMALE)
playsound(loc, "[species.female_scream_sound]", 80, 1)
else
playsound(loc, "[species.male_scream_sound]", 80, 1) //default to male screams if no gender is present.
*/
else
message = "makes a very loud noise."
m_type = 2
if("snap", "snaps")
m_type = 2
var/mob/living/carbon/human/H = src
var/obj/item/organ/external/L = H.get_organ("l_hand")
var/obj/item/organ/external/R = H.get_organ("r_hand")
var/left_hand_good = 0
var/right_hand_good = 0
if(L && (!(L.status & ORGAN_DESTROYED)) && (!(L.splinted)) && (!(L.status & ORGAN_BROKEN)))
left_hand_good = 1
if(R && (!(R.status & ORGAN_DESTROYED)) && (!(R.splinted)) && (!(R.status & ORGAN_BROKEN)))
right_hand_good = 1
if(!left_hand_good && !right_hand_good)
to_chat(usr, "You need at least one hand in good working order to snap your fingers.")
return
message = "snaps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] fingers."
playsound(loc, 'sound/effects/fingersnap.ogg', 50, 1, -3)
if("swish")
src.animate_tail_once()
@@ -597,18 +672,14 @@
return
if ("help")
src << {"blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag,
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom,
raise, salute, shake, shiver, shrug, sigh, signal-#1-10, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch,
twitch_v, vomit, whimper, wink, yawn"}
src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \
raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch, \
twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
if (message)
log_emote("[name]/[key] : [message]")
custom_emote(m_type,message)
@@ -82,6 +82,20 @@
var/datum/gender/T = gender_datums[get_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
else if(species && species.ambiguous_genders)
var/can_detect_gender = FALSE
if(isobserver(user)) // Ghosts are all knowing.
can_detect_gender = TRUE
if(issilicon(user)) // Borgs are too because science.
can_detect_gender = TRUE
else if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.species && istype(species, H.species))
can_detect_gender = TRUE
if(!can_detect_gender)
T = gender_datums[PLURAL] // Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species.
else
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
@@ -22,6 +22,14 @@
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
scream_verb = "shrieks"
male_scream_sound = 'sound/voice/shriek1.ogg'
female_scream_sound = 'sound/voice/shriek1.ogg'
male_cough_sounds = list('sound/voice/shriekcough.ogg')
female_cough_sounds = list('sound/voice/shriekcough.ogg')
male_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
female_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -50,6 +50,15 @@
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
var/female_scream_sound //= 'sound/goonstation/voice/female_scream.ogg' Removed due to licensing, replace!
var/male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
var/female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
var/male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'
var/female_sneeze_sound = 'sound/effects/mob_effects/f_sneeze.ogg'
// Combat vars.
var/total_health = 100 // Point at which the mob will enter crit.
var/list/unarmed_types = list( // Possible unarmed attacks that the mob will use in combat,
@@ -156,6 +165,7 @@
)
var/list/genders = list(MALE, FEMALE)
var/ambiguous_genders = FALSE // If true, people examining a member of this species whom are not also the same species will see them as gender neutral. Because aliens.
// Bump vars
var/bump_flag = HUMAN // What are we considered to be when bumped?
@@ -28,6 +28,9 @@ var/datum/species/shapeshifter/promethean/prometheans
breath_type = null
poison_type = null
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
gluttonous = 1
virus_immune = 1
blood_volume = 560
@@ -38,6 +38,8 @@
blood_volume = 400
hunger_factor = 0.2
ambiguous_genders = TRUE
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
bump_flag = MONKEY
@@ -162,6 +162,8 @@
darksight = 4
ambiguous_genders = TRUE
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
@@ -895,6 +895,11 @@ var/global/list/damage_icon_parts = list()
if(hud_used)
hud_used.hidden_inventory_update() //Updates the screenloc of the items on the 'other' inventory bar
//update whether handcuffs appears on our hud.
/mob/living/carbon/proc/update_hud_handcuffed()
if(hud_used && hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
hud_used.l_hand_hud_object.update_icon()
hud_used.r_hand_hud_object.update_icon()
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
if(handcuffed)
@@ -913,6 +918,8 @@ var/global/list/damage_icon_parts = list()
else
overlays_standing[HANDCUFF_LAYER] = null
update_hud_handcuffed()
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
+96 -85
View File
@@ -545,97 +545,108 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
return
var/input
if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member")
var/choice = alert("Would you like to select a hologram based on a (visible) crew member, switch to unique avatar, or load your character from your character slot?",,"Crew Member","Unique","My Character")
var/personnel_list[] = list()
switch(choice)
if("Crew Member") //A seeable crew member (or a dog)
var/list/targets = trackable_mobs()
if(targets.len)
input = input("Select a crew member:") as null|anything in targets //The definition of "crew member" is a little loose...
//This is torture, I know. If someone knows a better way...
if(!input) return
var/new_holo = getHologramIcon(getCompoundIcon(targets[input]))
qdel(holo_icon)
holo_icon = new_holo
for(var/datum/data/record/t in data_core.locked)//Look in data core locked.
personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image.
else
alert("No suitable records found. Aborting.")
if(personnel_list.len)
input = input("Select a crew member:") as null|anything in personnel_list
var/icon/character_icon = personnel_list[input]
if(character_icon)
qdel(holo_icon)//Clear old icon so we're not storing it in memory.
holo_icon = getHologramIcon(icon(character_icon))
else
alert("No suitable records found. Aborting.")
if("My Character") //Loaded character slot
if(!client || !client.prefs) return
var/mob/living/carbon/human/dummy/dummy = new ()
//This doesn't include custom_items because that's ... hard.
client.prefs.dress_preview_mob(dummy)
sleep(1 SECOND) //Strange bug in preview code? Without this, certain things won't show up. Yay race conditions?
dummy.regenerate_icons()
else
var/icon_list[] = list(
"default",
"floating face",
"singularity",
"drone",
"carp",
"spider",
"bear",
"slime",
"ian",
"runtime",
"poly",
"pun pun",
"male human",
"female human",
"male unathi",
"female unathi",
"male tajara",
"female tajara",
"male tesharii",
"female tesharii",
"male skrell",
"female skrell"
)
input = input("Please select a hologram:") as null|anything in icon_list
if(input)
var/new_holo = getHologramIcon(getCompoundIcon(dummy))
qdel(holo_icon)
switch(input)
if("default")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
if("floating face")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo2"))
if("singularity")
holo_icon = getHologramIcon(icon('icons/obj/singularity.dmi',"singularity_s1"))
if("drone")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"drone0"))
if("carp")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4"))
if("spider")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"nurse"))
if("bear")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"brownbear"))
if("slime")
holo_icon = getHologramIcon(icon('icons/mob/slimes.dmi',"cerulean adult slime"))
if("ian")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"corgi"))
if("runtime")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"cat"))
if("poly")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"parrot_fly"))
if("pun pun")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"punpun"))
if("male human")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holohumm"))
if("female human")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holohumf"))
if("male unathi")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holounam"))
if("female unathi")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holounaf"))
if("male tajara")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotajm"))
if("female tajara")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotajf"))
if("male tesharii")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotesm"))
if("female tesharii")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotesf"))
if("male skrell")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrm"))
if("female skrell")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrf"))
qdel(dummy)
holo_icon = new_holo
return
else //A premade from the dmi
var/icon_list[] = list(
"default",
"floating face",
"singularity",
"drone",
"carp",
"spider",
"bear",
"slime",
"ian",
"runtime",
"poly",
"pun pun",
"male human",
"female human",
"male unathi",
"female unathi",
"male tajara",
"female tajara",
"male tesharii",
"female tesharii",
"male skrell",
"female skrell"
)
input = input("Please select a hologram:") as null|anything in icon_list
if(input)
qdel(holo_icon)
switch(input)
if("default")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
if("floating face")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo2"))
if("singularity")
holo_icon = getHologramIcon(icon('icons/obj/singularity.dmi',"singularity_s1"))
if("drone")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"drone0"))
if("carp")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4"))
if("spider")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"nurse"))
if("bear")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"brownbear"))
if("slime")
holo_icon = getHologramIcon(icon('icons/mob/slimes.dmi',"cerulean adult slime"))
if("ian")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"corgi"))
if("runtime")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"cat"))
if("poly")
holo_icon = getHologramIcon(icon('icons/mob/animal.dmi',"parrot_fly"))
if("pun pun")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"punpun"))
if("male human")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holohumm"))
if("female human")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holohumf"))
if("male unathi")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holounam"))
if("female unathi")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holounaf"))
if("male tajara")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotajm"))
if("female tajara")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotajf"))
if("male tesharii")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotesm"))
if("female tesharii")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holotesf"))
if("male skrell")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrm"))
if("female skrell")
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrf"))
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
@@ -689,7 +689,7 @@
overlays += "eyes-[module_sprites[icontype]]"
if(opened)
var/panelprefix = custom_sprite ? src.ckey : "ov"
var/panelprefix = custom_sprite ? "[src.ckey]-[src.name]" : "ov"
if(wiresexposed)
overlays += "[panelprefix]-openpanel +w"
else if(cell)
@@ -208,6 +208,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/robot/medical/surgeon/New()
..()
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)
src.modules += new /obj/item/weapon/surgical/scalpel(src)
@@ -65,7 +65,13 @@
src.take_organ_damage(0,20,emp=1)
confused = (min(confused + 5, 30))
if(2)
src.take_organ_damage(0,15,emp=1)
confused = (min(confused + 4, 30))
if(3)
src.take_organ_damage(0,10,emp=1)
confused = (min(confused + 3, 30))
if(4)
src.take_organ_damage(0,5,emp=1)
confused = (min(confused + 2, 30))
flash_eyes(affect_silicon = 1)
src << "<span class='danger'><B>*BZZZT*</B></span>"
@@ -1,172 +1,204 @@
/mob/living/simple_animal/hostile/alien
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_dead = "alien_l"
icon_gib = "syndicate_gib"
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = -1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
a_intent = I_HURT
attack_sound = 'sound/weapons/bladeslice.ogg'
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 = "alien"
environment_smash = 2
status_flags = CANPUSH
minbodytemp = 0
heat_damage_per_tick = 20
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_dead = "aliend_l"
health = 60
melee_damage_lower = 15
melee_damage_upper = 15
/mob/living/simple_animal/hostile/alien/sentinel
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_dead = "aliens_l"
health = 120
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_dead = "alienq_l"
health = 250
maxHealth = 250
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
/mob/living/simple_animal/hostile/alien/queen/large
name = "alien empress"
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
move_to_delay = 4
maxHealth = 400
health = 400
/obj/item/projectile/neurotox
damage = 30
icon_state = "toxin"
/mob/living/simple_animal/hostile/alien/death()
..()
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
// Xenoarch aliens.
/mob/living/simple_animal/hostile/samak
name = "samak"
desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
faction = "samak"
icon_state = "samak"
icon_living = "samak"
icon_dead = "samak_dead"
icon = 'icons/jungle.dmi'
move_to_delay = 2
maxHealth = 125
health = 125
speed = 2
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "mauled"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Hruuugh!","Hrunnph")
emote_see = list("paws the ground","shakes its mane","stomps")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/diyaab
name = "diyaab"
desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
faction = "diyaab"
icon_state = "diyaab"
icon_living = "diyaab"
icon_dead = "diyaab_dead"
icon = 'icons/jungle.dmi'
move_to_delay = 1
maxHealth = 25
health = 25
speed = 1
melee_damage_lower = 1
melee_damage_upper = 8
attacktext = "gouged"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Awrr?","Aowrl!","Worrl")
emote_see = list("sniffs the air cautiously","looks around")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/shantak
name = "shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
faction = "shantak"
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'icons/jungle.dmi'
move_to_delay = 1
maxHealth = 75
health = 75
speed = 1
melee_damage_lower = 3
melee_damage_upper = 12
attacktext = "gouged"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Shuhn","Shrunnph?","Shunpf")
emote_see = list("scratches the ground","shakes out it's mane","tinkles gently")
/mob/living/simple_animal/yithian
name = "yithian"
desc = "A friendly creature vaguely resembling an oversized snail without a shell."
icon_state = "yithian"
icon_living = "yithian"
icon_dead = "yithian_dead"
icon = 'icons/jungle.dmi'
/mob/living/simple_animal/tindalos
name = "tindalos"
desc = "It looks like a large, flightless grasshopper."
icon_state = "tindalos"
icon_living = "tindalos"
icon_dead = "tindalos_dead"
icon = 'icons/jungle.dmi'
/mob/living/simple_animal/hostile/alien
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_dead = "alien_l"
icon_gib = "syndicate_gib"
faction = "xeno"
cooperative = 1
run_at_them = 0
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
maxHealth = 100
health = 100
speed = -1
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
attack_sound = 'sound/weapons/bladeslice.ogg'
a_intent = I_HURT
environment_smash = 2
status_flags = CANPUSH
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
heat_damage_per_tick = 20
unsuitable_atoms_damage = 15
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_dead = "aliend_l"
health = 60
melee_damage_lower = 15
melee_damage_upper = 15
/mob/living/simple_animal/hostile/alien/sentinel
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_dead = "aliens_l"
health = 120
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_dead = "alienq_l"
health = 250
maxHealth = 250
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
/mob/living/simple_animal/hostile/alien/queen/large
name = "alien empress"
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
move_to_delay = 4
maxHealth = 400
health = 400
/obj/item/projectile/neurotox
damage = 30
icon_state = "toxin"
/mob/living/simple_animal/hostile/alien/death()
..()
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
// Xenoarch aliens.
/mob/living/simple_animal/hostile/samak
name = "samak"
desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
faction = "samak"
icon_state = "samak"
icon_living = "samak"
icon_dead = "samak_dead"
icon = 'icons/jungle.dmi'
faction = "samak"
maxHealth = 125
health = 125
speed = 2
move_to_delay = 2
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "mauled"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Hruuugh!","Hrunnph")
emote_see = list("paws the ground","shakes its mane","stomps")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/diyaab
name = "diyaab"
desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
faction = "diyaab"
icon_state = "diyaab"
icon_living = "diyaab"
icon_dead = "diyaab_dead"
icon = 'icons/jungle.dmi'
faction = "diyaab"
cooperative = 1
maxHealth = 25
health = 25
speed = 1
move_to_delay = 1
melee_damage_lower = 1
melee_damage_upper = 8
attacktext = "gouged"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Awrr?","Aowrl!","Worrl")
emote_see = list("sniffs the air cautiously","looks around")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/shantak
name = "shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
faction = "shantak"
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'icons/jungle.dmi'
faction = "shantak"
maxHealth = 75
health = 75
speed = 1
move_to_delay = 1
melee_damage_lower = 3
melee_damage_upper = 12
attacktext = "gouged"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Shuhn","Shrunnph?","Shunpf")
emote_see = list("scratches the ground","shakes out it's mane","tinkles gently")
/mob/living/simple_animal/yithian
name = "yithian"
desc = "A friendly creature vaguely resembling an oversized snail without a shell."
icon_state = "yithian"
icon_living = "yithian"
icon_dead = "yithian_dead"
icon = 'icons/jungle.dmi'
faction = "yithian"
/mob/living/simple_animal/tindalos
name = "tindalos"
desc = "It looks like a large, flightless grasshopper."
icon_state = "tindalos"
icon_living = "tindalos"
icon_dead = "tindalos_dead"
icon = 'icons/jungle.dmi'
faction = "tindalos"
@@ -1,72 +1,73 @@
/mob/living/simple_animal/hostile/creature
name = "creature"
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/critter.dmi'
speak_emote = list("gibbers")
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
maxHealth = 40
health = 40
harm_intent_damage = 8
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "chomped"
attack_sound = 'sound/weapons/bite.ogg'
faction = "creature"
speed = 8
/mob/living/simple_animal/hostile/creature/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/creature/strong
maxHealth = 160
health = 160
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 25
/mob/living/simple_animal/hostile/creature/strong/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/creature
name = "creature"
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/critter.dmi'
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
faction = "creature"
maxHealth = 40
health = 40
speed = 8
harm_intent_damage = 8
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "chomped"
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("gibbers")
/mob/living/simple_animal/hostile/creature/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/creature/strong
maxHealth = 160
health = 160
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 25
/mob/living/simple_animal/hostile/creature/strong/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
@@ -1,39 +1,29 @@
//malfunctioning combat drones
/mob/living/simple_animal/hostile/retaliate/malf_drone
/mob/living/simple_animal/hostile/malf_drone
name = "combat drone"
desc = "An automated combat drone armed with state of the art weaponry and shielding."
icon_state = "drone3"
icon_living = "drone3"
icon_dead = "drone_dead"
ranged = 1
rapid = 1
speak_chance = 5
faction = "malf_drone"
maxHealth = 300
health = 300
speed = 8
stop_when_pulled = 0
turns_per_move = 3
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.")
emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity")
a_intent = I_HURT
stop_automated_movement_when_pulled = 0
health = 300
maxHealth = 300
speed = 8
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/beam/drone
projectilesound = 'sound/weapons/laser3.ogg'
destroy_surroundings = 0
var/datum/effect/effect/system/ion_trail_follow/ion_trail
//the drone randomly switches between these states because it's malfunctioning
var/hostile_drone = 0
//0 - retaliate, only attack enemies that attack it
//1 - hostile, attack everything that comes near
var/turf/patrol_target
var/explode_chance = 1
var/disabled = 0
var/exploding = 0
//Drones aren't affected by atmos.
min_oxy = 0
@@ -46,10 +36,19 @@
max_n2 = 0
minbodytemp = 0
var/has_loot = 1
faction = "malf_drone"
speak_chance = 5
speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.")
emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity")
/mob/living/simple_animal/hostile/retaliate/malf_drone/New()
var/datum/effect/effect/system/ion_trail_follow/ion_trail
var/turf/patrol_target
var/explode_chance = 1
var/disabled = 0
var/exploding = 0
var/has_loot = 1
/mob/living/simple_animal/hostile/malf_drone/New()
..()
if(prob(5))
projectiletype = /obj/item/projectile/beam/pulse/drone
@@ -58,17 +57,11 @@
ion_trail.set_up(src)
ion_trail.start()
/mob/living/simple_animal/hostile/retaliate/malf_drone/Process_Spacemove(var/check_drift = 0)
/mob/living/simple_animal/malf_drone/Process_Spacemove(var/check_drift = 0)
return 1
/mob/living/simple_animal/hostile/retaliate/malf_drone/ListTargets()
if(hostile_drone)
return view(src, 10)
else
return ..()
//self repair systems have a chance to bring the drone back to life
/mob/living/simple_animal/hostile/retaliate/malf_drone/Life()
/mob/living/simple_animal/hostile/malf_drone/Life()
//emps and lots of damage can temporarily shut us down
if(disabled > 0)
@@ -99,12 +92,12 @@
//sometimes our targetting sensors malfunction, and we attack anyone nearby
if(prob(disabled ? 0 : 1))
if(hostile_drone)
if(hostile)
src.visible_message("\blue \icon[src] [src] retracts several targetting vanes, and dulls it's running lights.")
hostile_drone = 0
hostile = 0
else
src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.")
hostile_drone = 1
hostile = 1
if(health / maxHealth > 0.9)
icon_state = "drone3"
@@ -151,18 +144,18 @@
..()
//ion rifle!
/mob/living/simple_animal/hostile/retaliate/malf_drone/emp_act(severity)
/mob/living/simple_animal/hostile/malf_drone/emp_act(severity)
health -= rand(3,15) * (severity + 1)
disabled = rand(150, 600)
hostile_drone = 0
hostile = 0
walk(src,0)
/mob/living/simple_animal/hostile/retaliate/malf_drone/death()
/mob/living/simple_animal/hostile/malf_drone/death()
..(null,"suddenly breaks apart.")
qdel(src)
/mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy()
//some random debris left behind
/mob/living/simple_animal/hostile/malf_drone/Destroy()
//More advanced than the default S_A loot system, for visual effect and random tech levels.
if(has_loot)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
@@ -1,83 +1,82 @@
/mob/living/simple_animal/hostile/faithless
name = "Faithless"
desc = "The Wish Granter's faith in humanity, incarnate"
icon_state = "faithless"
icon_living = "faithless"
icon_dead = "faithless_dead"
speak_chance = 0
turns_per_move = 5
response_help = "passes through"
response_disarm = "shoves"
response_harm = "hits"
speed = 8
maxHealth = 50
health = 50
harm_intent_damage = 10
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "gripped"
attack_sound = 'sound/hallucinations/growl1.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speed = 4
faction = "faithless"
/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/check_drift = 0)
return 1
/mob/living/simple_animal/hostile/faithless/FindTarget()
. = ..()
if(.)
audible_emote("wails at [.]")
/mob/living/simple_animal/hostile/faithless/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(12))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/faithless/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/faithless/strong
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 7
melee_damage_upper = 20
/mob/living/simple_animal/hostile/faithless/strong/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
/mob/living/simple_animal/hostile/faithless
name = "Faithless"
desc = "The Wish Granter's faith in humanity, incarnate"
icon_state = "faithless"
icon_living = "faithless"
icon_dead = "faithless_dead"
faction = "faithless"
maxHealth = 50
health = 50
speed = 8
turns_per_move = 5
response_help = "passes through"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 10
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "gripped"
attack_sound = 'sound/hallucinations/growl1.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speak_chance = 0
/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/check_drift = 0)
return 1
/mob/living/simple_animal/hostile/faithless/set_target()
. = ..()
if(.)
audible_emote("wails at [target_mob]")
/mob/living/simple_animal/hostile/faithless/PunchTarget()
. = ..()
var/mob/living/L = .
if(istype(L))
if(prob(12))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/faithless/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/faithless/strong
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 7
melee_damage_upper = 20
/mob/living/simple_animal/hostile/faithless/strong/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
check_horde()
@@ -1,107 +1,111 @@
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
/mob/living/simple_animal/hostile/hivebot
name = "Hivebot"
desc = "A small robot"
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
health = 15
maxHealth = 15
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "clawed"
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = "hivebot"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speed = 4
/mob/living/simple_animal/hostile/hivebot/range
name = "Hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
/mob/living/simple_animal/hostile/hivebot/strong
name = "Strong Hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death()
..()
visible_message("<b>[src]</b> blows apart!")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
qdel(src)
return
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
name = "Beacon"
desc = "Some odd beacon thing"
icon = 'icons/mob/hivebot.dmi'
icon_state = "def_radar-off"
icon_living = "def_radar-off"
health = 200
maxHealth = 200
status_flags = 0
anchored = 1
stop_automated_movement = 1
var/bot_type = "norm"
var/bot_amt = 10
var/spawn_delay = 600
var/turn_on = 0
var/auto_spawn = 1
proc
warpbots()
New()
..()
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(5, 0, src.loc)
smoke.start()
visible_message("\red <B>The [src] warps in!</B>")
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
warpbots()
icon_state = "def_radar"
visible_message("\red The [src] turns on!")
while(bot_amt > 0)
bot_amt--
switch(bot_type)
if("norm")
new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
if("range")
new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
if("rapid")
new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
spawn(100)
qdel(src)
return
Life()
..()
if(stat == 0)
if(prob(2))//Might be a bit low, will mess with it likely
warpbots()
/mob/living/simple_animal/hostile/hivebot
name = "Hivebot"
desc = "A small robot"
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
faction = "hivebot"
maxHealth = 15
health = 15
speed = 4
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "clawed"
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
/mob/living/simple_animal/hostile/hivebot/range
name = "Hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
/mob/living/simple_animal/hostile/hivebot/range/rapid
rapid = 1
/mob/living/simple_animal/hostile/hivebot/strong
name = "Strong Hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death()
..()
visible_message("<b>[src]</b> blows apart!")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
qdel(src)
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
name = "Beacon"
desc = "Some odd beacon thing"
icon = 'icons/mob/hivebot.dmi'
icon_state = "def_radar-off"
icon_living = "def_radar-off"
health = 200
maxHealth = 200
status_flags = 0
anchored = 1
wander = 0
stop_automated_movement = 1
var/bot_type = "norm"
var/bot_amt = 10
var/spawn_delay = 600
var/turn_on = 0
var/auto_spawn = 1
proc
warpbots()
New()
..()
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(5, 0, src.loc)
smoke.start()
visible_message("\red <B>The [src] warps in!</B>")
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
warpbots()
icon_state = "def_radar"
visible_message("\red The [src] turns on!")
while(bot_amt > 0)
bot_amt--
switch(bot_type)
if("norm")
new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
if("range")
new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
if("rapid")
new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src))
spawn(100)
qdel(src)
return
Life()
..()
if(stat == 0)
if(prob(2))//Might be a bit low, will mess with it likely
warpbots()
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
@@ -1,195 +1,196 @@
//
// Abstract Class
//
/mob/living/simple_animal/hostile/mimic
name = "crate"
desc = "A rectangular steel crate."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
icon_living = "crate"
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
response_help = "touches"
response_disarm = "pushes"
response_harm = "hits"
speed = 4
maxHealth = 250
health = 250
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "attacked"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
faction = "mimic"
move_to_delay = 8
/mob/living/simple_animal/hostile/mimic/FindTarget()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/mimic/death()
..()
qdel(src)
//
// Crate Mimic
//
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
/mob/living/simple_animal/hostile/mimic/crate
attacktext = "bitten"
stop_automated_movement = 1
wander = 0
var/attempt_open = 0
// Pickup loot
/mob/living/simple_animal/hostile/mimic/crate/initialize()
..()
for(var/obj/item/I in loc)
I.loc = src
/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings()
..()
if(prob(90))
icon_state = "[initial(icon_state)]open"
else
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/ListTargets()
if(attempt_open)
return ..()
return view(src, 1)
/mob/living/simple_animal/hostile/mimic/crate/FindTarget()
. = ..()
if(.)
trigger()
/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget()
. = ..()
if(.)
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/proc/trigger()
if(!attempt_open)
visible_message("<b>[src]</b> starts to move!")
attempt_open = 1
/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage)
trigger()
..(damage)
/mob/living/simple_animal/hostile/mimic/crate/LoseTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/LostTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/death()
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
O.loc = C
..()
/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(2)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
//
// Copy Mimic
//
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
/mob/living/simple_animal/hostile/mimic/copy
health = 100
maxHealth = 100
var/mob/living/creator = null // the creator
var/destroy_objects = 0
var/knockdown_people = 0
/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
..(loc)
CopyObject(copy, creator)
/mob/living/simple_animal/hostile/mimic/copy/death()
for(var/atom/movable/M in src)
M.loc = get_turf(src)
..()
/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
// Return a list of targets that isn't the creator
. = ..()
return . - creator
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
O.loc = src
name = O.name
desc = O.desc
icon = O.icon
icon_state = O.icon_state
icon_living = icon_state
if(istype(O, /obj/structure))
health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
knockdown_people = 1
melee_damage_lower *= 2
melee_damage_upper *= 2
else if(istype(O, /obj/item))
var/obj/item/I = O
health = 15 * I.w_class
melee_damage_lower = 2 + I.force
melee_damage_upper = 2 + I.force
move_to_delay = 2 * I.w_class
maxHealth = health
if(creator)
src.creator = creator
faction = "\ref[creator]" // very unique
return 1
return
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
if(destroy_objects)
..()
/mob/living/simple_animal/hostile/mimic/copy/AttackingTarget()
. =..()
if(knockdown_people)
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(1)
//
// Abstract Class
//
/mob/living/simple_animal/hostile/mimic
name = "crate"
desc = "A rectangular steel crate."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
icon_living = "crate"
faction = "mimic"
maxHealth = 250
health = 250
speed = 4
move_to_delay = 8
response_help = "touches"
response_disarm = "pushes"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "attacked"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
/mob/living/simple_animal/hostile/mimic/set_target()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/mimic/death()
..()
qdel(src)
//
// Crate Mimic
//
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
/mob/living/simple_animal/hostile/mimic/crate
attacktext = "bitten"
stop_automated_movement = 1
wander = 0
var/attempt_open = 0
// Pickup loot
/mob/living/simple_animal/hostile/mimic/crate/initialize()
..()
for(var/obj/item/I in loc)
I.forceMove(src)
/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings()
..()
if(prob(90))
icon_state = "[initial(icon_state)]open"
else
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/ListTargets()
if(attempt_open)
return ..()
else
return ..(1)
/mob/living/simple_animal/hostile/mimic/crate/set_target()
. = ..()
if(.)
trigger()
/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
. = ..()
if(.)
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/proc/trigger()
if(!attempt_open)
visible_message("<b>[src]</b> starts to move!")
attempt_open = 1
/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage)
trigger()
..(damage)
/mob/living/simple_animal/hostile/mimic/crate/LoseTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/LostTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/death()
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
O.forceMove(C)
..()
/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(2)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
//
// Copy Mimic
//
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
/mob/living/simple_animal/hostile/mimic/copy
health = 100
maxHealth = 100
var/mob/living/creator = null // the creator
var/destroy_objects = 0
var/knockdown_people = 0
/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
..(loc)
CopyObject(copy, creator)
/mob/living/simple_animal/hostile/mimic/copy/death()
for(var/atom/movable/M in src)
M.forceMove(get_turf(src))
..()
/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
// Return a list of targets that isn't the creator
. = ..()
return . - creator
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
O.forceMove(src)
name = O.name
desc = O.desc
icon = O.icon
icon_state = O.icon_state
icon_living = icon_state
if(istype(O, /obj/structure))
health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
knockdown_people = 1
melee_damage_lower *= 2
melee_damage_upper *= 2
else if(istype(O, /obj/item))
var/obj/item/I = O
health = 15 * I.w_class
melee_damage_lower = 2 + I.force
melee_damage_upper = 2 + I.force
move_to_delay = 2 * I.w_class
maxHealth = health
if(creator)
src.creator = creator
faction = "\ref[creator]" // very unique
return 1
return
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
if(destroy_objects)
..()
/mob/living/simple_animal/hostile/mimic/copy/PunchTarget()
. =..()
if(knockdown_people)
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(1)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -1,52 +1,59 @@
/mob/living/simple_animal/shade
name = "Shade"
real_name = "Shade"
desc = "A bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "shade"
icon_living = "shade"
icon_dead = "shade_dead"
maxHealth = 50
health = 50
universal_speak = 1
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
response_help = "puts their hand through"
response_disarm = "flails at"
response_harm = "punches"
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "drained the life from"
minbodytemp = 0
maxbodytemp = 4000
min_oxy = 0
max_co2 = 0
max_tox = 0
speed = -1
stop_automated_movement = 1
status_flags = 0
faction = "cult"
status_flags = CANPUSH
/mob/living/simple_animal/shade/cultify()
return
/mob/living/simple_animal/shade/Life()
..()
OnDeathInLife()
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/device/soulstone))
var/obj/item/device/soulstone/S = O;
S.transfer_soul("SHADE", src, user)
return
/mob/living/simple_animal/shade/proc/OnDeathInLife()
if(stat == 2)
new /obj/item/weapon/ectoplasm (src.loc)
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
M.show_message("\red [src] lets out a contented sigh as their form unwinds. ")
ghostize()
qdel(src)
return
/mob/living/simple_animal/shade
name = "Shade"
real_name = "Shade"
desc = "A bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "shade"
icon_living = "shade"
icon_dead = "shade_dead"
faction = "cult"
maxHealth = 50
health = 50
speed = -1
response_help = "puts their hand through"
response_disarm = "flails at"
response_harm = "punches"
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "drained the life from"
minbodytemp = 0
maxbodytemp = 4000
min_oxy = 0
max_co2 = 0
max_tox = 0
stop_automated_movement = 1
wander = 0
status_flags = 0
speak_chance = 5
universal_speak = 1
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
loot_list = list(/obj/item/weapon/ectoplasm = 100)
/mob/living/simple_animal/shade/cultify()
return
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/device/soulstone))
var/obj/item/device/soulstone/S = O;
S.transfer_soul("SHADE", src, user)
return
..()
/mob/living/simple_animal/shade/death()
..()
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
M.show_message("\red [src] lets out a contented sigh as their form unwinds. ")
ghostize()
qdel(src)
return
@@ -1,76 +1,78 @@
/mob/living/simple_animal/hostile/scarybat
name = "space bats"
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
icon = 'icons/mob/bats.dmi'
icon_state = "bat"
icon_living = "bat"
icon_dead = "bat_dead"
icon_gib = "bat_dead"
speak_chance = 0
turns_per_move = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speed = 4
maxHealth = 20
health = 20
harm_intent_damage = 10
melee_damage_lower = 3
melee_damage_upper = 3
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
environment_smash = 1
faction = "scarybat"
var/mob/living/owner
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
..()
if(istype(L))
owner = L
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
return ..() //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/scarybat/FindTarget()
. = ..()
if(.)
emote("flutters towards [.]")
/mob/living/simple_animal/hostile/scarybat/Found(var/atom/A)//This is here as a potential override to pick a specific target if available
if(istype(A) && A == owner)
return 0
return ..()
/mob/living/simple_animal/hostile/scarybat/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Stun(1)
L.visible_message("<span class='danger'>\the [src] scares \the [L]!</span>")
/mob/living/simple_animal/hostile/scarybat/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/scarybat/cult/cultify()
return
/mob/living/simple_animal/hostile/scarybat/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/scarybat
name = "space bats"
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
icon = 'icons/mob/bats.dmi'
icon_state = "bat"
icon_living = "bat"
icon_dead = "bat_dead"
icon_gib = "bat_dead"
faction = "scarybat"
maxHealth = 20
health = 20
turns_per_move = 3
speed = 4
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 10
melee_damage_lower = 3
melee_damage_upper = 3
environment_smash = 1
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/mob/living/owner
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
..()
if(istype(L))
owner = L
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
return ..()
/mob/living/simple_animal/hostile/scarybat/set_target()
. = ..()
if(.)
emote("flutters towards [.]")
/mob/living/simple_animal/hostile/scarybat/ListTargets()
. = ..()
if(owner)
return . - owner
/mob/living/simple_animal/hostile/scarybat/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Stun(1)
L.visible_message("<span class='danger'>\the [src] scares \the [L]!</span>")
/mob/living/simple_animal/hostile/scarybat/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/scarybat/cult/cultify()
return
/mob/living/simple_animal/hostile/scarybat/cult/Life()
..()
check_horde()
@@ -1,172 +1,125 @@
//Space bears!
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "RawrRawr!!"
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"
icon_gib = "bear_gib"
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
stop_automated_movement_when_pulled = 0
maxHealth = 60
health = 60
melee_damage_lower = 20
melee_damage_upper = 30
//Space bears aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
var/stance_step = 0
faction = "russian"
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
/mob/living/simple_animal/hostile/bear/Hudson
name = "Hudson"
desc = ""
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
/mob/living/simple_animal/hostile/bear/Life()
. =..()
if(!.)
return
if(loc && istype(loc,/turf/space))
icon_state = "bear"
else
icon_state = "bearfloor"
switch(stance)
if(STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(target_mob && target_mob in ListTargets(10))
stance = STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
stance = STANCE_IDLE
if(STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
if(target_mob && target_mob in ListTargets(10))
if(!(SA_attackable(target_mob)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
if(!found_mob)
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
stance = STANCE_IDLE
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
stance = STANCE_ATTACK
if(STANCE_ATTACKING)
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
custom_emote(1, "is worn out and needs to rest." )
stance = STANCE_TIRED
stance_step = 0
walk(src, 0) //This stops the bear's walking
return
/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(stance != STANCE_ATTACK && stance != STANCE_ATTACKING)
stance = STANCE_ALERT
stance_step = 6
target_mob = user
..()
/mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob)
if(stance != STANCE_ATTACK && stance != STANCE_ATTACKING)
stance = STANCE_ALERT
stance_step = 6
target_mob = M
..()
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
return //No drifting in space for space bears!
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
if(.)
custom_emote(1,"stares alertly at [.]")
stance = STANCE_ALERT
/mob/living/simple_animal/hostile/bear/LoseTarget()
..(5)
/mob/living/simple_animal/hostile/bear/AttackingTarget()
if(!Adjacent(target_mob))
return
custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
var/damage = rand(melee_damage_lower, melee_damage_upper)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
//else if(istype(target_mob,/obj/mecha))
//var/obj/mecha/M = target_mob
//M.attack_animal(src)
//return M
//Space bears!
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "RawrRawr!!"
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"
icon_gib = "bear_gib"
faction = "russian"
cooperative = 1
maxHealth = 60
health = 60
turns_per_move = 5
see_in_dark = 6
stop_when_pulled = 0
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
melee_damage_lower = 20
melee_damage_upper = 30
//Space bears aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speak_chance = 1
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
var/stance_step = 0
/mob/living/simple_animal/hostile/bear/handle_stance()
switch(stance)
if(STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(target_mob && target_mob in ListTargets(10))
handle_stance(STANCE_ATTACK) //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
handle_stance(STANCE_IDLE)
if(STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
if(target_mob && target_mob in ListTargets(10))
if(!(SA_attackable(target_mob)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
if(!found_mob)
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
handle_stance(STANCE_IDLE)
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
handle_stance(STANCE_ATTACK)
if(STANCE_ATTACKING)
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
custom_emote(1, "is worn out and needs to rest." )
handle_stance(STANCE_TIRED)
stance_step = 0
walk(src, 0) //This stops the bear's walking
return
else
..()
/mob/living/simple_animal/hostile/bear/update_icons()
..()
if(!stat)
if(loc && istype(loc,/turf/space))
icon_state = "bear"
else
icon_state = "bearfloor"
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
if(.)
custom_emote(1,"stares alertly at [.]")
handle_stance(STANCE_ALERT)
/mob/living/simple_animal/hostile/bear/PunchTarget()
if(!Adjacent(target_mob))
return
custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
var/damage = rand(melee_damage_lower, melee_damage_upper)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
else
..()
@@ -1,55 +1,52 @@
/mob/living/simple_animal/hostile/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
speak_chance = 0
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speed = 4
maxHealth = 25
health = 25
harm_intent_damage = 8
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
break_stuff_probability = 15
faction = "carp"
/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/carp/FindTarget()
. = ..()
if(.)
custom_emote(1,"nashes at [.]")
/mob/living/simple_animal/hostile/carp/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
/mob/living/simple_animal/hostile/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
faction = "carp"
maxHealth = 25
health = 25
speed = 4
turns_per_move = 5
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 8
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/carp/set_target()
. = ..()
if(.)
custom_emote(1,"nashes at [.]")
/mob/living/simple_animal/hostile/carp/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -6,55 +6,44 @@
item_state = "cat2"
icon_living = "cat2"
icon_dead = "cat2_dead"
hostile = 1 //To mice, anyway.
investigates = 1
specific_targets = 1 //Only targets with Found()
run_at_them = 0 //DOMESTICATED
view_range = 5
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
holder_type = /obj/item/weapon/holder/cat
mob_size = MOB_SMALL
speak_chance = 1
speak = list("Meow!","Esp!","Purr!","HSSSSS")
speak_emote = list("purrs", "meows")
emote_hear = list("meows","mews")
emote_see = list("shakes their head", "shivers")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
say_maybe_target = list("Meow?","Mew?","Mao?")
say_got_target = list("MEOW!","HSSSS!","REEER!")
meat_amount = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
var/turns_since_scan = 0
var/mob/living/simple_animal/mouse/movement_target
var/mob/flee_target
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
holder_type = /obj/item/weapon/holder/cat
mob_size = MOB_SMALL
/mob/living/simple_animal/cat/Life()
//MICE!
if((src.loc) && isturf(src.loc))
if(!stat && !resting && !buckled)
for(var/mob/living/simple_animal/mouse/M in loc)
if(!M.stat)
M.splat()
visible_emote(pick("bites \the [M]!","toys with \the [M].","chomps on \the [M]!"))
movement_target = null
stop_automated_movement = 0
break
..()
for(var/mob/living/simple_animal/mouse/snack in oview(src,5))
if(snack.stat < DEAD && prob(15))
audible_emote(pick("hisses and spits!","mrowls fiercely!","eyes [snack] hungrily."))
break
if(!stat && !resting && !buckled)
turns_since_scan++
if (turns_since_scan > 5)
walk_to(src,0)
turns_since_scan = 0
if (flee_target) //fleeing takes precendence
handle_flee_target()
else
handle_movement_target()
. = ..()
if(!.) return
if(prob(2)) //spooky
var/mob/observer/dead/spook = locate() in range(src,5)
@@ -68,104 +57,60 @@
var/atom/A = pick(visible)
visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].")
/mob/living/simple_animal/cat/proc/handle_movement_target()
//if our target is neither inside a turf or inside a human(???), stop
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
//if we have no target or our current one is out of sight/too far away
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
movement_target = null
stop_automated_movement = 0
for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target
if(isturf(snack.loc) && !snack.stat)
movement_target = snack
break
handle_flee_target()
if(movement_target)
stop_automated_movement = 1
walk_to(src,movement_target,0,3)
/mob/living/simple_animal/cat/PunchTarget()
if(istype(target_mob,/mob/living/simple_animal/mouse))
var/mob/living/simple_animal/mouse/mouse = target_mob
mouse.splat()
visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!"))
return mouse
else
..()
/mob/living/simple_animal/cat/Found(var/atom/found_atom)
if(istype(found_atom,/mob/living/simple_animal/mouse) && SA_attackable(found_atom))
return found_atom
/mob/living/simple_animal/cat/proc/handle_flee_target()
//see if we should stop fleeing
if (flee_target && !(flee_target.loc in view(src)))
if (flee_target && !(flee_target in ListTargets(view_range)))
flee_target = null
stop_automated_movement = 0
GiveUpMoving()
if (flee_target)
if (flee_target && !stat && !buckled)
if (resting)
lay_down()
if(prob(25)) say("HSSSSS")
stop_automated_movement = 1
walk_away(src, flee_target, 7, 2)
/mob/living/simple_animal/cat/proc/set_flee_target(atom/A)
if(A)
flee_target = A
turns_since_scan = 5
/mob/living/simple_animal/cat/attackby(var/obj/item/O, var/mob/user)
. = ..()
if(O.force)
set_flee_target(user? user : src.loc)
/mob/living/simple_animal/cat/attack_hand(mob/living/carbon/human/M as mob)
. = ..()
if(M.a_intent == I_HURT)
set_flee_target(M)
/mob/living/simple_animal/cat/react_to_attack(var/atom/A)
if(A == src) return
flee_target = A
turns_since_scan = 5
/mob/living/simple_animal/cat/ex_act()
. = ..()
set_flee_target(src.loc)
/mob/living/simple_animal/cat/bullet_act(var/obj/item/projectile/proj)
. = ..()
set_flee_target(proj.firer? proj.firer : src.loc)
/mob/living/simple_animal/cat/hitby(atom/movable/AM)
. = ..()
set_flee_target(AM.thrower? AM.thrower : src.loc)
react_to_attack(src.loc)
//Basic friend AI
/mob/living/simple_animal/cat/fluff
var/mob/living/carbon/human/friend
var/befriend_job = null
/mob/living/simple_animal/cat/fluff/handle_movement_target()
if (friend)
var/follow_dist = 4
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
follow_dist = 1
else if (friend.stat || friend.health <= 50) //danger or just sleeping
follow_dist = 2
var/near_dist = max(follow_dist - 2, 1)
var/current_dist = get_dist(src, friend)
if (movement_target != friend)
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src)))
//stop existing movement
walk_to(src,0)
turns_since_scan = 0
//walk to friend
stop_automated_movement = 1
movement_target = friend
walk_to(src, movement_target, near_dist, 4)
//already following and close enough, stop
else if (current_dist <= near_dist)
walk_to(src,0)
movement_target = null
stop_automated_movement = 0
if (prob(10))
say("Meow!")
if (!friend || movement_target != friend)
..()
/mob/living/simple_animal/cat/fluff/Life()
..()
if (stat || !friend)
return
if (get_dist(src, friend) <= 1)
. = ..()
if(!. || ai_inactive || !friend) return
var/friend_dist = get_dist(src,friend)
if (friend_dist <= 4)
if(stance == STANCE_IDLE)
if(set_follow(friend))
handle_stance(STANCE_FOLLOW)
if (friend_dist <= 1)
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
if (prob((friend.stat < DEAD)? 50 : 15))
var/verb = pick("meows", "mews", "mrowls")
@@ -213,6 +158,7 @@
item_state = "cat"
icon_living = "cat"
icon_dead = "cat_dead"
befriend_job = "Chief Medical Officer"
/mob/living/simple_animal/cat/kitten
name = "kitten"
@@ -1,217 +1,227 @@
//Corgi
/mob/living/simple_animal/corgi
name = "\improper corgi"
real_name = "corgi"
desc = "It's a corgi."
icon_state = "corgi"
icon_living = "corgi"
icon_dead = "corgi_dead"
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
emote_hear = list("barks", "woofs", "yaps","pants")
emote_see = list("shakes its head", "shivers")
speak_chance = 1
turns_per_move = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
meat_amount = 3
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
see_in_dark = 5
mob_size = 8
var/obj/item/inventory_head
var/obj/item/inventory_back
//IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Ian
name = "Ian"
real_name = "Ian" //Intended to hold the name without altering it.
gender = MALE
desc = "It's a corgi."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
/mob/living/simple_animal/corgi/Ian/Life()
..()
//Feeding, chasing food, FOOOOODDDD
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
turns_since_scan = 0
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
movement_target = null
stop_automated_movement = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3))
if(isturf(S.loc) || ishuman(S.loc))
movement_target = S
break
if(movement_target)
stop_automated_movement = 1
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if (movement_target.loc.x < src.x)
set_dir(WEST)
else if (movement_target.loc.x > src.x)
set_dir(EAST)
else if (movement_target.loc.y < src.y)
set_dir(SOUTH)
else if (movement_target.loc.y > src.y)
set_dir(NORTH)
else
set_dir(SOUTH)
if(isturf(movement_target.loc) )
UnarmedAttack(movement_target)
else if(ishuman(movement_target.loc) && prob(20))
visible_emote("stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.")
if(prob(1))
visible_emote(pick("dances around","chases their tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
name = "Corgi meat"
desc = "Tastes like... well you know..."
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/weapon/newspaper))
if(!stat)
for(var/mob/M in viewers(user, null))
if ((M.client && !( M.blinded )))
M.show_message("\blue [user] baps [name] on the nose with the rolled up [O]")
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2))
set_dir(i)
sleep(1)
else
..()
/mob/living/simple_animal/corgi/regenerate_icons()
overlays = list()
if(inventory_head)
var/head_icon_state = inventory_head.icon_state
if(health <= 0)
head_icon_state += "2"
var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state)
if(head_icon)
overlays += head_icon
if(inventory_back)
var/back_icon_state = inventory_back.icon_state
if(health <= 0)
back_icon_state += "2"
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
if(back_icon)
overlays += back_icon
return
/mob/living/simple_animal/corgi/puppy
name = "\improper corgi puppy"
real_name = "corgi"
desc = "It's a corgi puppy."
icon_state = "puppy"
icon_living = "puppy"
icon_dead = "puppy_dead"
//pupplies cannot wear anything.
/mob/living/simple_animal/corgi/puppy/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
usr << "\red You can't fit this on [src]"
return
..()
//LISA! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Lisa
name = "Lisa"
real_name = "Lisa"
gender = FEMALE
desc = "It's a corgi with a cute pink bow."
icon_state = "lisa"
icon_living = "lisa"
icon_dead = "lisa_dead"
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
var/turns_since_scan = 0
var/puppies = 0
//Lisa already has a cute bow!
/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
usr << "\red [src] already has a cute bow!"
return
..()
/mob/living/simple_animal/corgi/Lisa/Life()
..()
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 15)
turns_since_scan = 0
var/alone = 1
var/ian = 0
for(var/mob/M in oviewers(7, src))
if(istype(M, /mob/living/simple_animal/corgi/Ian))
if(M.client)
alone = 0
break
else
ian = M
else
alone = 0
break
if(alone && ian && puppies < 4)
if(near_camera(src) || near_camera(ian))
return
new /mob/living/simple_animal/corgi/puppy(loc)
if(prob(1))
visible_emote(pick("dances around","chases her tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
//Technically this should be like, its own file or something or a subset of dog but whatever. Not a coder.
/mob/living/simple_animal/corgi/tamaskan
name = "\improper tamaskan"
real_name = "tamaskan"
desc = "It's a tamaskan."
icon_state = "tamaskan"
icon_living = "tamaskan"
icon_dead = "tamaskan_dead"
/mob/living/simple_animal/corgi/tamaskan/spice
name = "Spice"
real_name = "Spice" //Intended to hold the name without altering it.
gender = FEMALE
desc = "It's a tamaskan, the name Spice can be found on its collar."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
//Corgi
/mob/living/simple_animal/corgi
name = "\improper corgi"
real_name = "corgi"
desc = "It's a corgi."
icon_state = "corgi"
icon_living = "corgi"
icon_dead = "corgi_dead"
run_at_them = 0
turns_per_move = 10
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
see_in_dark = 5
mob_size = 8
speak_chance = 1
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
emote_hear = list("barks", "woofs", "yaps","pants")
emote_see = list("shakes its head", "shivers")
meat_amount = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
var/obj/item/inventory_head
var/obj/item/inventory_back
//IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Ian
name = "Ian"
real_name = "Ian" //Intended to hold the name without altering it.
gender = MALE
desc = "It's a corgi."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
/mob/living/simple_animal/corgi/Ian/Life()
..()
//Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically.
//Feeding, chasing food, FOOOOODDDD
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
turns_since_scan = 0
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
movement_target = null
stop_automated_movement = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3))
if(isturf(S.loc) || ishuman(S.loc))
movement_target = S
break
if(movement_target)
stop_automated_movement = 1
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if (movement_target.loc.x < src.x)
set_dir(WEST)
else if (movement_target.loc.x > src.x)
set_dir(EAST)
else if (movement_target.loc.y < src.y)
set_dir(SOUTH)
else if (movement_target.loc.y > src.y)
set_dir(NORTH)
else
set_dir(SOUTH)
if(isturf(movement_target.loc) )
UnarmedAttack(movement_target)
else if(ishuman(movement_target.loc) && prob(20))
visible_emote("stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.")
if(prob(1))
visible_emote(pick("dances around","chases their tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
name = "Corgi meat"
desc = "Tastes like... well you know..."
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/weapon/newspaper))
if(!stat)
for(var/mob/M in viewers(user, null))
if ((M.client && !( M.blinded )))
M.show_message("\blue [user] baps [name] on the nose with the rolled up [O]")
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2))
set_dir(i)
sleep(1)
else
..()
/mob/living/simple_animal/corgi/regenerate_icons()
overlays = list()
if(inventory_head)
var/head_icon_state = inventory_head.icon_state
if(health <= 0)
head_icon_state += "2"
var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state)
if(head_icon)
overlays += head_icon
if(inventory_back)
var/back_icon_state = inventory_back.icon_state
if(health <= 0)
back_icon_state += "2"
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
if(back_icon)
overlays += back_icon
return
/mob/living/simple_animal/corgi/puppy
name = "\improper corgi puppy"
real_name = "corgi"
desc = "It's a corgi puppy."
icon_state = "puppy"
icon_living = "puppy"
icon_dead = "puppy_dead"
//pupplies cannot wear anything.
/mob/living/simple_animal/corgi/puppy/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
usr << "\red You can't fit this on [src]"
return
..()
//LISA! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Lisa
name = "Lisa"
real_name = "Lisa"
gender = FEMALE
desc = "It's a corgi with a cute pink bow."
icon_state = "lisa"
icon_living = "lisa"
icon_dead = "lisa_dead"
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
var/turns_since_scan = 0
var/puppies = 0
//Lisa already has a cute bow!
/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
usr << "\red [src] already has a cute bow!"
return
..()
/mob/living/simple_animal/corgi/Lisa/Life()
..()
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 15)
turns_since_scan = 0
var/alone = 1
var/ian = 0
for(var/mob/M in oviewers(7, src))
if(istype(M, /mob/living/simple_animal/corgi/Ian))
if(M.client)
alone = 0
break
else
ian = M
else
alone = 0
break
if(alone && ian && puppies < 4)
if(near_camera(src) || near_camera(ian))
return
new /mob/living/simple_animal/corgi/puppy(loc)
if(prob(1))
visible_emote(pick("dances around","chases her tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
//Technically this should be like, its own file or something or a subset of dog but whatever. Not a coder.
/mob/living/simple_animal/corgi/tamaskan
name = "\improper tamaskan"
real_name = "tamaskan"
desc = "It's a tamaskan."
icon_state = "tamaskan"
icon_living = "tamaskan"
icon_dead = "tamaskan_dead"
retaliate = 1 //Tamaskans are bigass dogs, okay?
/mob/living/simple_animal/corgi/tamaskan/spice
name = "Spice"
real_name = "Spice" //Intended to hold the name without altering it.
gender = FEMALE
desc = "It's a tamaskan, the name Spice can be found on its collar."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
@@ -1,42 +1,46 @@
//Look Sir, free crabs!
/mob/living/simple_animal/crab
name = "crab"
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
mob_size = MOB_SMALL
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
speak_chance = 1
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
stop_automated_movement = 1
friendly = "pinches"
mob_size = 5
var/obj/item/inventory_head
var/obj/item/inventory_mask
/mob/living/simple_animal/crab/Life()
..()
//CRAB movement
if(!ckey && !stat)
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
Move(get_step(src,pick(4,8)))
turns_since_move = 0
regenerate_icons()
//COFFEE! SQUEEEEEEEEE!
/mob/living/simple_animal/crab/Coffee
name = "Coffee"
real_name = "Coffee"
desc = "It's Coffee, the other pet!"
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
//Look Sir, free crabs!
/mob/living/simple_animal/crab
name = "crab"
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
wander = 0
stop_automated_movement = 1
turns_per_move = 5
mob_size = MOB_SMALL
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
friendly = "pinches"
speak_chance = 1
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
var/obj/item/inventory_head
var/obj/item/inventory_mask
/mob/living/simple_animal/crab/Life()
..()
//CRAB movement, I'm not porting this up to SA because... "sideways-only movement" var nothanks
if(!ckey && !stat)
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
lifes_since_move++
if(lifes_since_move >= turns_per_move)
Move(get_step(src,pick(4,8)))
lifes_since_move = 0
regenerate_icons()
//COFFEE! SQUEEEEEEEEE!
/mob/living/simple_animal/crab/Coffee
name = "Coffee"
real_name = "Coffee"
desc = "It's Coffee, the other pet!"
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
@@ -1,268 +1,282 @@
//goat
/mob/living/simple_animal/hostile/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
speak = list("EHEHEHEHEH","eh?")
speak_emote = list("brays")
emote_hear = list("brays")
emote_see = list("shakes its head", "stamps a foot", "glares around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 4
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
faction = "goat"
attacktext = "kicked"
health = 40
melee_damage_lower = 1
melee_damage_upper = 5
var/datum/reagents/udder = null
/mob/living/simple_animal/hostile/retaliate/goat/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/hostile/retaliate/goat/Life()
. = ..()
if(.)
//chance to go crazy and start wacking stuff
if(!enemies.len && prob(1))
Retaliate()
if(enemies.len && prob(10))
enemies = list()
LoseTarget()
src.visible_message("\blue [src] calms down.")
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
if(locate(/obj/effect/plant) in loc)
var/obj/effect/plant/SV = locate() in loc
SV.die_off(1)
if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc)
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc
qdel(SP)
if(!pulledby)
var/obj/effect/plant/food
food = locate(/obj/effect/plant) in oview(5,loc)
if(food)
var/step = get_step_to(src, food, 0)
Move(step)
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
..()
if(stat == CONSCIOUS)
visible_message("<span class='warning'>[src] gets an evil-looking gleam in their eye.</span>")
/mob/living/simple_animal/hostile/retaliate/goat/Move()
..()
if(!stat)
for(var/obj/effect/plant/SV in loc)
SV.die_off(1)
/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
if(!transfered)
user << "\red The udder is dry. Wait a bit longer..."
else
..()
//cow
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
icon_gib = "cow_gib"
speak = list("moo?","moo","MOOOOOO")
speak_emote = list("moos","moos hauntingly")
emote_hear = list("brays")
emote_see = list("shakes its head")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
health = 50
var/datum/reagents/udder = null
/mob/living/simple_animal/cow/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
if(!transfered)
user << "\red The udder is dry. Wait a bit longer..."
else
..()
/mob/living/simple_animal/cow/Life()
. = ..()
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead)
M.visible_message("<span class='warning'>[M] tips over [src].</span>","<span class='notice'>You tip over [src].</span>")
Weaken(30)
icon_state = icon_dead
spawn(rand(20,50))
if(!stat && M)
icon_state = icon_living
var/list/responses = list( "[src] looks at you imploringly.",
"[src] looks at you pleadingly",
"[src] looks at you with a resigned expression.",
"[src] seems resigned to its fate.")
M << pick(responses)
else
..()
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps its tiny wings")
speak_chance = 2
turns_per_move = 2
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 1
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
health = 1
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE
mob_size = MOB_MINISCULE
/mob/living/simple_animal/chick/New()
..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/chick/Life()
. =..()
if(!.)
return
if(!stat)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/chicken(src.loc)
qdel(src)
var/const/MAX_CHICKENS = 50
var/global/chicken_count = 0
/mob/living/simple_animal/chicken
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"
speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps its wings viciously")
speak_chance = 2
turns_per_move = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 2
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
health = 10
var/eggsleft = 0
var/body_color
pass_flags = PASSTABLE
mob_size = MOB_SMALL
/mob/living/simple_animal/chicken/New()
..()
if(!body_color)
body_color = pick( list("brown","black","white") )
icon_state = "chicken_[body_color]"
icon_living = "chicken_[body_color]"
icon_dead = "chicken_[body_color]_dead"
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
chicken_count += 1
/mob/living/simple_animal/chicken/death()
..()
chicken_count -= 1
/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
if(G.seed && G.seed.kitchen_tag == "wheat")
if(!stat && eggsleft < 8)
user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.")
user.drop_item()
qdel(O)
eggsleft += rand(1, 4)
else
user << "\blue [name] doesn't seem hungry!"
else
user << "[name] doesn't seem interested in that."
else
..()
/mob/living/simple_animal/chicken/Life()
. =..()
if(!.)
return
if(!stat && prob(3) && eggsleft > 0)
visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
eggsleft--
var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
if(chicken_count < MAX_CHICKENS && prob(10))
processing_objects.Add(E)
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/chick(get_turf(src))
processing_objects.Remove(src)
qdel(src)
else
processing_objects.Remove(src)
//goat
/mob/living/simple_animal/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
faction = "goat"
health = 40
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
melee_damage_lower = 1
melee_damage_upper = 5
attacktext = "kicked"
speak_chance = 1
speak = list("EHEHEHEHEH","eh?")
speak_emote = list("brays")
emote_hear = list("brays")
emote_see = list("shakes its head", "stamps a foot", "glares around")
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null
/mob/living/simple_animal/retaliate/goat/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/retaliate/goat/Life()
. = ..()
if(.)
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
if(locate(/obj/effect/plant) in loc)
var/obj/effect/plant/SV = locate() in loc
SV.die_off(1)
if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc)
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc
qdel(SP)
if(!pulledby)
var/obj/effect/plant/food
food = locate(/obj/effect/plant) in oview(5,loc)
if(food)
var/step = get_step_to(src, food, 0)
Move(step)
/mob/living/simple_animal/retaliate/goat/react_to_attack()
. = ..()
if(.)
visible_message("<span class='warning'>[src] gets an evil-looking gleam in their eye.</span>")
/mob/living/simple_animal/retaliate/goat/Move()
..()
if(!stat)
for(var/obj/effect/plant/SV in loc)
SV.die_off(1)
/mob/living/simple_animal/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
if(!transfered)
user << "\red The udder is dry. Wait a bit longer..."
else
..()
//cow
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
icon_gib = "cow_gib"
health = 50
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
speak_chance = 1
speak = list("moo?","moo","MOOOOOO")
speak_emote = list("moos","moos hauntingly")
emote_hear = list("brays")
emote_see = list("shakes its head")
meat_amount = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null
/mob/living/simple_animal/cow/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
if(!transfered)
user << "\red The udder is dry. Wait a bit longer..."
else
..()
/mob/living/simple_animal/cow/Life()
. = ..()
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead)
M.visible_message("<span class='warning'>[M] tips over [src].</span>","<span class='notice'>You tip over [src].</span>")
Weaken(30)
icon_state = icon_dead
spawn(rand(20,50))
if(!stat && M)
icon_state = icon_living
var/list/responses = list( "[src] looks at you imploringly.",
"[src] looks at you pleadingly",
"[src] looks at you with a resigned expression.",
"[src] seems resigned to its fate.")
M << pick(responses)
else
..()
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
health = 1
turns_per_move = 2
pass_flags = PASSTABLE | PASSGRILLE
mob_size = MOB_MINISCULE
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
speak_chance = 2
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps its tiny wings")
meat_amount = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/amount_grown = 0
/mob/living/simple_animal/chick/New()
..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/chick/Life()
. =..()
if(!.)
return
if(!stat)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/chicken(src.loc)
qdel(src)
var/const/MAX_CHICKENS = 50
var/global/chicken_count = 0
/mob/living/simple_animal/chicken
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"
health = 10
turns_per_move = 3
pass_flags = PASSTABLE
mob_size = MOB_SMALL
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicked"
speak_chance = 2
speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps its wings viciously")
meat_amount = 2
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/eggsleft = 0
var/body_color
/mob/living/simple_animal/chicken/New()
..()
if(!body_color)
body_color = pick( list("brown","black","white") )
icon_state = "chicken_[body_color]"
icon_living = "chicken_[body_color]"
icon_dead = "chicken_[body_color]_dead"
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
chicken_count += 1
/mob/living/simple_animal/chicken/death()
..()
chicken_count -= 1
/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
if(G.seed && G.seed.kitchen_tag == "wheat")
if(!stat && eggsleft < 8)
user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.")
user.drop_item()
qdel(O)
eggsleft += rand(1, 4)
else
user << "\blue [name] doesn't seem hungry!"
else
user << "[name] doesn't seem interested in that."
else
..()
/mob/living/simple_animal/chicken/Life()
. =..()
if(!.)
return
if(!stat && prob(3) && eggsleft > 0)
visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
eggsleft--
var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
if(chicken_count < MAX_CHICKENS && prob(10))
processing_objects.Add(E)
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/chick(get_turf(src))
processing_objects.Remove(src)
qdel(src)
else
processing_objects.Remove(src)
@@ -0,0 +1,239 @@
#define SPINNING_WEB 1
#define LAYING_EGGS 2
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
//basic spider mob, these generally guard nests
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and black, it makes you shudder to look at it. This one has deep red eyes."
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
faction = "spiders"
maxHealth = 200
health = 200
pass_flags = PASSTABLE
move_to_delay = 6
speed = 3
stop_when_pulled = 0
turns_per_move = 5
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
melee_damage_lower = 15
melee_damage_upper = 20
heat_damage_per_tick = 20
cold_damage_per_tick = 20
speak_chance = 5
speak_emote = list("chitters")
emote_hear = list("chitters")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
var/busy = 0
var/poison_per_bite = 5
var/poison_chance = 10
var/poison_type = "spidertoxin"
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
desc = "Furry and black, it makes you shudder to look at it. This one has brilliant green eyes."
icon_state = "nurse"
icon_living = "nurse"
icon_dead = "nurse_dead"
maxHealth = 40
health = 40
melee_damage_lower = 5
melee_damage_upper = 10
poison_per_bite = 7
poison_type = "stoxin"
var/fed = 0
var/atom/cocoon_target
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
icon_state = "hunter"
icon_living = "hunter"
icon_dead = "hunter_dead"
maxHealth = 120
health = 120
move_to_delay = 4
melee_damage_lower = 10
melee_damage_upper = 20
poison_per_bite = 5
/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent)
get_light_and_color(parent)
..()
/mob/living/simple_animal/hostile/giant_spider/PunchTarget()
. = ..()
if(isliving(.))
var/mob/living/L = .
if(L.reagents)
L.reagents.add_reagent(poison_type, poison_per_bite)
if(prob(poison_chance))
L << "<span class='warning'>You feel a tiny prick.</span>"
L.reagents.add_reagent(poison_type, poison_per_bite)
/mob/living/simple_animal/hostile/giant_spider/nurse/PunchTarget()
. = ..()
if(ishuman(.))
var/mob/living/carbon/human/H = .
if(prob(5))
var/obj/item/organ/external/O = pick(H.organs)
if(!(O.robotic >= ORGAN_ROBOT))
var/eggcount
for(var/obj/I in O.implants)
if(istype(I, /obj/effect/spider/eggcluster))
eggcount ++
if(!eggcount)
var/eggs = PoolOrNew(/obj/effect/spider/eggcluster/small, list(O, src))
O.implants += eggs
H << "<span class='warning'>The [src] injects something into your [O.name]!</span>"
/mob/living/simple_animal/hostile/giant_spider/handle_stance()
. = ..()
if(ai_inactive) return
switch(stance)
if(STANCE_IDLE)
//1% chance to skitter madly away
if(!busy && prob(1))
/*var/list/move_targets = list()
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
walk_to(src, pick(orange(20, src)), 1, move_to_delay)
spawn(5 SECONDS)
stop_automated_movement = 0
walk(src,0)
/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C)
spawn(10 SECONDS)
if(busy == MOVING_TO_TARGET)
if(cocoon_target == C && get_dist(src,cocoon_target) > 1)
cocoon_target = null
busy = 0
stop_automated_movement = 0
/mob/living/simple_animal/hostile/giant_spider/nurse/Life()
. = ..()
if(!. || ai_inactive) return
if(stance == STANCE_IDLE)
var/list/can_see = view(src, 10)
//30% chance to stop wandering and do something
if(!busy && prob(30))
//first, check for potential food nearby to cocoon
for(var/mob/living/C in can_see)
if(C.stat)
cocoon_target = C
busy = MOVING_TO_TARGET
walk_to(src, C, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(C)
return
//second, spin a sticky spiderweb on this tile
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
busy = SPINNING_WEB
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance.</span>")
stop_automated_movement = 1
spawn(40)
if(busy == SPINNING_WEB)
new /obj/effect/spider/stickyweb(src.loc)
busy = 0
stop_automated_movement = 0
else
//third, lay an egg cluster there
var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
if(!E && fed > 0)
busy = LAYING_EGGS
src.visible_message("<span class='notice'>\The [src] begins to lay a cluster of eggs.</span>")
stop_automated_movement = 1
spawn(50)
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
PoolOrNew(/obj/effect/spider/eggcluster, list(loc, src))
fed--
busy = 0
stop_automated_movement = 0
else
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
for(var/obj/O in can_see)
if(O.anchored)
continue
if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, O, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(O)
else if(busy == MOVING_TO_TARGET && cocoon_target)
if(get_dist(src, cocoon_target) <= 1)
busy = SPINNING_COCOON
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance around \the [cocoon_target].</span>")
stop_automated_movement = 1
walk(src,0)
spawn(50)
if(busy == SPINNING_COCOON)
if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
for(var/mob/living/M in C.loc)
if(istype(M, /mob/living/simple_animal/hostile/giant_spider))
continue
large_cocoon = 1
fed++
src.visible_message("<span class='warning'>\The [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.</span>")
M.forceMove(C)
C.pixel_x = M.pixel_x
C.pixel_y = M.pixel_y
break
for(var/obj/item/I in C.loc)
I.forceMove(C)
for(var/obj/structure/S in C.loc)
if(!S.anchored)
S.forceMove(C)
large_cocoon = 1
for(var/obj/machinery/M in C.loc)
if(!M.anchored)
M.forceMove(C)
large_cocoon = 1
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
busy = 0
stop_automated_movement = 0
else
busy = 0
stop_automated_movement = 0
#undef SPINNING_WEB
#undef LAYING_EGGS
#undef MOVING_TO_TARGET
#undef SPINNING_COCOON
@@ -1,5 +1,3 @@
/mob/living/simple_animal/hostile/goose
name = "space goose"
desc = "That's no duck. That's a space goose. You have a bad feeling about this."
@@ -7,15 +5,18 @@
icon_living = "goose"
icon_dead = "goose_dead"
icon_gib = "generic_gib"
speak_chance = 0
faction = "geese"
maxHealth = 15
health = 15
speed = 4
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speed = 4
maxHealth = 15 //nothing an unarmed crewmember shouldn't be able to stomp into the dirt, if they're alone.
health = 15
harm_intent_damage = 5
melee_damage_lower = 5 //they're meant to be annoying, not threatening.
@@ -23,12 +24,34 @@
attacktext = "pecked"
attack_sound = 'sound/weapons/bite.ogg'
break_stuff_probability = 5
//SPACE geese aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
faction = "geese"
speak_chance = 10
speak = list("HONK!")
emote_hear = list("honks loudly!")
emote_see = list()
say_understood = list()
say_cannot = list()
say_maybe_target = list("Honk?")
say_got_target = list("HONK!!!")
reactions = list()
/mob/living/simple_animal/hostile/goose/FindTarget()
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
/mob/living/simple_animal/hostile/goose/set_target()
. = ..()
if(.)
custom_emote(1,"flaps and honks at [.]!")
custom_emote(1,"flaps and honks at [.]!")
/mob/living/simple_animal/hostile/goose/Process_Spacemove(var/check_drift = 0)
return
@@ -1,17 +1,22 @@
/mob/living/simple_animal/lizard
name = "Lizard"
desc = "A cute tiny lizard."
icon = 'icons/mob/critter.dmi'
icon_state = "lizard"
icon_living = "lizard"
icon_dead = "lizard-dead"
speak_emote = list("hisses")
health = 5
maxHealth = 5
attacktext = "bitten"
melee_damage_lower = 1
melee_damage_upper = 2
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
mob_size = MOB_MINISCULE
/mob/living/simple_animal/lizard
name = "Lizard"
desc = "A cute tiny lizard."
icon = 'icons/mob/critter.dmi'
icon_state = "lizard"
icon_living = "lizard"
icon_dead = "lizard-dead"
health = 5
maxHealth = 5
mob_size = MOB_MINISCULE
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
attacktext = "bitten"
melee_damage_lower = 1
melee_damage_upper = 2
speak_chance = 1
speak_emote = list("hisses")
@@ -1,130 +1,136 @@
/mob/living/simple_animal/mouse
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
icon_state = "mouse_gray"
item_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
speak = list("Squeek!","SQUEEK!","Squeek?")
speak_emote = list("squeeks","squeeks","squiks")
emote_hear = list("squeeks","squeaks","squiks")
emote_see = list("runs in a circle", "shakes", "scritches at something")
pass_flags = PASSTABLE
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
maxHealth = 5
health = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stamps on"
density = 0
var/body_color //brown, gray and white, leave blank for random
layer = MOB_LAYER
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
universal_speak = 0
universal_understand = 1
holder_type = /obj/item/weapon/holder/mouse
mob_size = MOB_MINISCULE
can_pull_size = ITEMSIZE_TINY
can_pull_mobs = MOB_PULL_NONE
/mob/living/simple_animal/mouse/Life()
..()
if(!stat && prob(speak_chance))
for(var/mob/M in view())
M << 'sound/effects/mousesqueek.ogg'
if(!ckey && stat == CONSCIOUS && prob(0.5))
stat = UNCONSCIOUS
icon_state = "mouse_[body_color]_sleep"
wander = 0
speak_chance = 0
//snuffles
else if(stat == UNCONSCIOUS)
if(ckey || prob(1))
stat = CONSCIOUS
icon_state = "mouse_[body_color]"
wander = 1
else if(prob(5))
audible_emote("snuffles.")
/mob/living/simple_animal/mouse/lay_down() //Simply turns sprite into sleeping and back upon using "Rest".
..()
icon_state = resting ? "mouse_[body_color]_sleep" : "mouse_[body_color]"
/mob/living/simple_animal/mouse/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
real_name = name
if(!body_color)
body_color = pick( list("brown","gray","white") )
icon_state = "mouse_[body_color]"
item_state = "mouse_[body_color]"
icon_living = "mouse_[body_color]"
icon_dead = "mouse_[body_color]_dead"
desc = "It's a small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
src.stat = DEAD
src.icon_dead = "mouse_[body_color]_splat"
src.icon_state = "mouse_[body_color]_splat"
layer = MOB_LAYER
if(client)
client.time_died_as_mouse = world.time
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
M << "\blue \icon[src] Squeek!"
M << 'sound/effects/mousesqueek.ogg'
..()
/mob/living/simple_animal/mouse/death()
layer = MOB_LAYER
if(client)
client.time_died_as_mouse = world.time
..()
/*
* Mouse types
*/
/mob/living/simple_animal/mouse/white
body_color = "white"
icon_state = "mouse_white"
/mob/living/simple_animal/mouse/gray
body_color = "gray"
icon_state = "mouse_gray"
/mob/living/simple_animal/mouse/brown
body_color = "brown"
icon_state = "mouse_brown"
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_animal/mouse/brown/Tom
name = "Tom"
desc = "Jerry the cat is not amused."
/mob/living/simple_animal/mouse/brown/Tom/New()
..()
// Change my name back, don't want to be named Tom (666)
name = initial(name)
/mob/living/simple_animal/mouse/cannot_use_vents()
return
/mob/living/simple_animal/mouse
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
icon_state = "mouse_gray"
item_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
maxHealth = 5
health = 5
turns_per_move = 5
see_in_dark = 6
universal_understand = 1
mob_size = MOB_MINISCULE
pass_flags = PASSTABLE
can_pull_size = ITEMSIZE_TINY
can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
density = 0
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stamps on"
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
speak_chance = 1
speak = list("Squeek!","SQUEEK!","Squeek?")
speak_emote = list("squeeks","squeeks","squiks")
emote_hear = list("squeeks","squeaks","squiks")
emote_see = list("runs in a circle", "shakes", "scritches at something")
holder_type = /obj/item/weapon/holder/mouse
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/body_color //brown, gray and white, leave blank for random
/mob/living/simple_animal/mouse/Life()
. = ..()
if(!. || ai_inactive) return
if(prob(speak_chance))
for(var/mob/M in view())
M << 'sound/effects/mousesqueek.ogg'
if(!ckey && stat == CONSCIOUS && prob(0.5))
stat = UNCONSCIOUS
icon_state = "mouse_[body_color]_sleep"
wander = 0
speak_chance = 0
//snuffles
else if(stat == UNCONSCIOUS)
if(ckey || prob(1))
stat = CONSCIOUS
icon_state = "mouse_[body_color]"
wander = 1
else if(prob(5))
audible_emote("snuffles.")
/mob/living/simple_animal/mouse/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
real_name = name
if(!body_color)
body_color = pick( list("brown","gray","white") )
icon_state = "mouse_[body_color]"
item_state = "mouse_[body_color]"
icon_living = "mouse_[body_color]"
icon_dead = "mouse_[body_color]_dead"
icon_rest = "mouse_[body_color]_sleep"
desc = "It's a small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
src.stat = DEAD
src.icon_dead = "mouse_[body_color]_splat"
src.icon_state = "mouse_[body_color]_splat"
layer = MOB_LAYER
if(client)
client.time_died_as_mouse = world.time
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
M << "\blue \icon[src] Squeek!"
M << 'sound/effects/mousesqueek.ogg'
..()
/mob/living/simple_animal/mouse/death()
layer = MOB_LAYER
if(client)
client.time_died_as_mouse = world.time
..()
/*
* Mouse types
*/
/mob/living/simple_animal/mouse/white
body_color = "white"
icon_state = "mouse_white"
/mob/living/simple_animal/mouse/gray
body_color = "gray"
icon_state = "mouse_gray"
/mob/living/simple_animal/mouse/brown
body_color = "brown"
icon_state = "mouse_brown"
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_animal/mouse/brown/Tom
name = "Tom"
desc = "Jerry the cat is not amused."
/mob/living/simple_animal/mouse/brown/Tom/New()
..()
// Change my name back, don't want to be named Tom (666)
name = initial(name)
/mob/living/simple_animal/mouse/cannot_use_vents()
return
@@ -5,15 +5,21 @@
icon_living = "penguin"
icon_dead = "penguin_dead"
icon_gib = "generic_gib"
speak_chance = 0
turns_per_move = 5
maxHealth = 20
health = 20
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
turns_per_move = 5
response_help = "pets"
response_disarm = "pushes aside"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_upper = 15
melee_damage_lower = 10
attacktext = "pecked"
melee_damage_upper = 15
attacktext = "pecked"
speak_chance = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
@@ -1,59 +1,69 @@
/mob/living/simple_animal/slime
name = "pet slime"
desc = "A lovable, domesticated slime."
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
icon_living = "grey baby slime"
icon_dead = "grey baby slime dead"
speak_emote = list("chirps")
health = 100
maxHealth = 100
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/slime/science
name = "Kendrick"
colour = "rainbow"
icon_state = "rainbow baby slime"
icon_living = "rainbow baby slime"
icon_dead = "rainbow baby slime dead"
/mob/living/simple_animal/slime/science/initialize()
..()
overlays.Cut()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime
name = "pet slime"
desc = "A lovable, domesticated slime."
icon = 'icons/mob/slimes.dmi'
health = 200
maxHealth = 200
icon_state = "grey adult slime"
icon_living = "grey adult slime"
icon_dead = "grey baby slime dead"
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/adultslime/New()
..()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime/death()
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
S1.icon_state = "[src.colour] baby slime"
S1.icon_living = "[src.colour] baby slime"
S1.icon_dead = "[src.colour] baby slime dead"
S1.colour = "[src.colour]"
var/mob/living/simple_animal/slime/S2 = new /mob/living/simple_animal/slime (src.loc)
S2.icon_state = "[src.colour] baby slime"
S2.icon_living = "[src.colour] baby slime"
S2.icon_dead = "[src.colour] baby slime dead"
S2.colour = "[src.colour]"
/mob/living/simple_animal/slime
name = "pet slime"
desc = "A lovable, domesticated slime."
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
icon_living = "grey baby slime"
icon_dead = "grey baby slime dead"
maxHealth = 100
health = 100
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
speak_chance = 1
speak_emote = list("chirps")
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/slime/science
name = "Kendrick"
colour = "rainbow"
icon_state = "rainbow baby slime"
icon_living = "rainbow baby slime"
icon_dead = "rainbow baby slime dead"
/mob/living/simple_animal/slime/science/initialize()
..()
overlays.Cut()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime
name = "pet slime"
desc = "A lovable, domesticated slime."
icon = 'icons/mob/slimes.dmi'
icon_state = "grey adult slime"
icon_living = "grey adult slime"
icon_dead = "grey baby slime dead"
maxHealth = 200
health = 200
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
speak_chance = 1
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/adultslime/New()
..()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime/death()
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
S1.icon_state = "[src.colour] baby slime"
S1.icon_living = "[src.colour] baby slime"
S1.icon_dead = "[src.colour] baby slime dead"
S1.colour = "[src.colour]"
var/mob/living/simple_animal/slime/S2 = new /mob/living/simple_animal/slime (src.loc)
S2.icon_state = "[src.colour] baby slime"
S2.icon_living = "[src.colour] baby slime"
S2.icon_dead = "[src.colour] baby slime dead"
S2.colour = "[src.colour]"
qdel(src)
@@ -1,11 +1,35 @@
/mob/living/simple_animal/spiderbot
name = "spider-bot"
desc = "A skittering robotic friend!"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
icon_dead = "spiderbot-smashed"
health = 10
maxHealth = 10
wander = 0
speed = -1 //Spiderbots gotta go fast.
pass_flags = PASSTABLE
mob_size = MOB_SMALL
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
melee_damage_lower = 1
melee_damage_upper = 3
attacktext = "shocked"
min_oxy = 0
max_tox = 0
max_co2 = 0
minbodytemp = 0
maxbodytemp = 500
mob_size = MOB_SMALL
speak_chance = 1
speak_emote = list("beeps","clicks","chirps")
var/obj/item/device/radio/borg/radio = null
var/mob/living/silicon/ai/connected_ai = null
@@ -15,31 +39,8 @@
var/list/req_access = list(access_robotics) //Access needed to pop out the brain.
var/positronic
name = "spider-bot"
desc = "A skittering robotic friend!"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
icon_dead = "spiderbot-smashed"
wander = 0
health = 10
maxHealth = 10
attacktext = "shocked"
melee_damage_lower = 1
melee_damage_upper = 3
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
var/emagged = 0
var/obj/item/held_item = null //Storage for single item they can hold.
speed = -1 //Spiderbots gotta go fast.
pass_flags = PASSTABLE
speak_emote = list("beeps","clicks","chirps")
/mob/living/simple_animal/spiderbot/New()
..()
@@ -87,7 +88,7 @@
src.mmi = O
src.transfer_personality(O)
O.loc = src
O.forceMove(src)
src.update_icon()
return 1
@@ -122,7 +123,7 @@
user << "<span class='notice'>You swipe your access card and pop the brain out of \the [src].</span>"
eject_brain()
if(held_item)
held_item.loc = src.loc
held_item.forceMove(src.loc)
held_item = null
return 1
else
@@ -171,7 +172,7 @@
if(mmi)
var/turf/T = get_turf(loc)
if(T)
mmi.loc = T
mmi.forceMove(T)
if(mind) mind.transfer_to(mmi.brainmob)
mmi = null
real_name = initial(real_name)
@@ -201,7 +202,7 @@
if(camera)
camera.status = 0
held_item.loc = src.loc
held_item.forceMove(src.loc)
held_item = null
gibs(loc, null, null, /obj/effect/gibspawner/robot) //TODO: use gib() or refactor spiderbots into synthetics.
@@ -226,7 +227,7 @@
"<span class='danger'>You launch \the [held_item]!</span>", \
"You hear a skittering noise and a thump!")
var/obj/item/weapon/grenade/G = held_item
G.loc = src.loc
G.forceMove(src.loc)
G.prime()
held_item = null
return 1
@@ -235,7 +236,7 @@
"<span class='notice'>You drop \the [held_item].</span>", \
"You hear a skittering noise and a soft thump.")
held_item.loc = src.loc
held_item.forceMove(src.loc)
held_item = null
return 1
@@ -264,7 +265,7 @@
for(var/obj/item/I in view(1, src))
if(selection == I)
held_item = selection
selection.loc = src
selection.forceMove(src)
visible_message("<span class='notice'>\The [src] scoops up \the [held_item].</span>", \
"<span class='notice'>You grab \the [held_item].</span>", \
"You hear a skittering noise and a clink.")
@@ -284,4 +285,4 @@
return
/mob/living/simple_animal/spiderbot/binarycheck()
return positronic
return positronic
@@ -1,18 +1,22 @@
/mob/living/simple_animal/tomato
name = "tomato"
desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!"
icon_state = "tomato"
icon_living = "tomato"
icon_dead = "tomato_dead"
speak_chance = 0
turns_per_move = 5
maxHealth = 15
health = 15
meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat
response_help = "prods"
response_disarm = "pushes aside"
response_harm = "smacks"
harm_intent_damage = 5
melee_damage_upper = 15
melee_damage_lower = 10
attacktext = "mauled"
/mob/living/simple_animal/hostile/tomato
name = "tomato"
desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!"
icon_state = "tomato"
icon_living = "tomato"
icon_dead = "tomato_dead"
faction = "plants"
maxHealth = 15
health = 15
turns_per_move = 5
response_help = "prods"
response_disarm = "pushes aside"
response_harm = "smacks"
harm_intent_damage = 5
melee_damage_upper = 15
melee_damage_lower = 10
attacktext = "mauled"
meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat
@@ -1,56 +1,57 @@
/mob/living/simple_animal/hostile/tree
name = "pine tree"
desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
speak_chance = 0
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
response_help = "brushes"
response_disarm = "pushes"
response_harm = "hits"
speed = -1
maxHealth = 250
health = 250
pixel_x = -16
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
faction = "carp"
/mob/living/simple_animal/hostile/tree/FindTarget()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/tree/death()
..(null,"is hacked into pieces!")
new /obj/item/stack/material/wood(loc)
/mob/living/simple_animal/hostile/tree
name = "pine tree"
desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
faction = "carp" //Trees can be carp friends?
maxHealth = 250
health = 250
speed = -1
turns_per_move = 5
response_help = "brushes"
response_disarm = "pushes"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
pixel_x = -16
/mob/living/simple_animal/hostile/tree/FindTarget()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/tree/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/tree/death()
..(null,"is hacked into pieces!")
new /obj/item/stack/material/wood(loc)
qdel(src)
@@ -1,200 +1,198 @@
/mob/living/simple_animal/space_worm
name = "space worm segment"
desc = "A part of a space worm."
icon = 'icons/mob/animal.dmi'
icon_state = "spaceworm"
icon_living = "spaceworm"
icon_dead = "spacewormdead"
status_flags = 0
speak_emote = list("transmits") //not supposed to be used under AI control
emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks
response_help = "touches"
response_disarm = "flails at"
response_harm = "punches the"
harm_intent_damage = 2
maxHealth = 30
health = 30
universal_speak =1
stop_automated_movement = 1
animate_movement = SYNC_STEPS
minbodytemp = 0
maxbodytemp = 350
min_oxy = 0
max_co2 = 0
max_tox = 0
a_intent = I_HURT //so they don't get pushed around
environment_smash = 2
speed = -1
var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly
var/mob/living/simple_animal/space_worm/next //head is the nextest segment
var/stomachProcessProbability = 50
var/digestionProbability = 20
var/flatPlasmaValue = 5 //flat plasma amount given for non-items
var/atom/currentlyEating //what the worm is currently eating
var/eatingDuration = 0 //how long he's been eating it for
head
name = "space worm head"
icon_state = "spacewormhead"
icon_living = "spacewormhead"
icon_dead = "spacewormdead"
maxHealth = 20
health = 20
melee_damage_lower = 10
melee_damage_upper = 15
attacktext = "bitten"
animate_movement = SLIDE_STEPS
New(var/location, var/segments = 6)
..()
var/mob/living/simple_animal/space_worm/current = src
for(var/i = 1 to segments)
var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc)
current.Attach(newSegment)
current = newSegment
update_icon()
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
icon_state = "spacewormhead[previous?1:0]"
if(previous)
set_dir(get_dir(previous,src))
else
icon_state = "spacewormheaddead"
Life()
..()
if(next && !(next in view(src,1)))
Detach()
if(stat == DEAD) //dead chunks fall off and die immediately
if(previous)
previous.Detach()
if(next)
Detach(1)
if(prob(stomachProcessProbability))
ProcessStomach()
update_icon()
return
Destroy() //if a chunk a destroyed, make a new worm out of the split halves
if(previous)
previous.Detach()
..()
Move()
var/attachementNextPosition = loc
if(..())
if(previous)
previous.Move(attachementNextPosition)
update_icon()
Bump(atom/obstacle)
if(currentlyEating != obstacle)
currentlyEating = obstacle
eatingDuration = 0
if(!AttemptToEat(obstacle))
eatingDuration++
else
currentlyEating = null
eatingDuration = 0
return
update_icon() //only for the sake of consistency with the other update icon procs
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
if(previous) //midsection
icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below
else //tail
icon_state = "spacewormtail"
set_dir(get_dir(src,next)) //next will always be present since it's not a head and if it's dead, it goes in the other if branch
else
icon_state = "spacewormdead"
return
proc/AttemptToEat(var/atom/target)
if(istype(target,/turf/simulated/wall))
var/turf/simulated/wall/W = target
if((!W.reinf_material && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
W.dismantle_wall()
return 1
else if(istype(target,/atom/movable))
if(istype(target,/mob) || eatingDuration >= 50) //5 ticks to eat stuff like airlocks
var/atom/movable/objectOrMob = target
contents += objectOrMob
return 1
return 0
proc/Attach(var/mob/living/simple_animal/space_worm/attachement)
if(!attachement)
return
previous = attachement
attachement.next = src
return
proc/Detach(die = 0)
var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0)
var/mob/living/simple_animal/space_worm/newHeadPrevious = previous
previous = null //so that no extra heads are spawned
newHead.Attach(newHeadPrevious)
if(die)
newHead.death()
qdel(src)
proc/ProcessStomach()
for(var/atom/movable/stomachContent in contents)
if(prob(digestionProbability))
if(istype(stomachContent,/obj/item/stack)) //converts to plasma, keeping the stack value
if(!istype(stomachContent,/obj/item/stack/material/phoron))
var/obj/item/stack/oldStack = stomachContent
new /obj/item/stack/material/phoron(src, oldStack.get_amount())
qdel(oldStack)
continue
else if(istype(stomachContent,/obj/item)) //converts to plasma, keeping the w_class
var/obj/item/oldItem = stomachContent
new /obj/item/stack/material/phoron(src, oldItem.w_class)
qdel(oldItem)
continue
else
new /obj/item/stack/material/phoron(src, flatPlasmaValue) //just flat amount
qdel(stomachContent)
continue
if(previous)
for(var/atom/movable/stomachContent in contents) //transfer it along the digestive tract
previous.contents += stomachContent
else
for(var/atom/movable/stomachContent in contents) //or poop it out
loc.contents += stomachContent
return
/mob/living/simple_animal/space_worm
name = "space worm segment"
desc = "A part of a space worm."
icon = 'icons/mob/animal.dmi'
icon_state = "spaceworm"
icon_living = "spaceworm"
icon_dead = "spacewormdead"
maxHealth = 30
health = 30
speed = -1
status_flags = 0
universal_speak = 1
stop_automated_movement = 1
wander = 0
animate_movement = SYNC_STEPS
response_help = "touches"
response_disarm = "flails at"
response_harm = "punches the"
harm_intent_damage = 2
minbodytemp = 0
maxbodytemp = 350
min_oxy = 0
max_co2 = 0
max_tox = 0
environment_smash = 2
speak_emote = list("transmits") //not supposed to be used under AI control
emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks
var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly
var/mob/living/simple_animal/space_worm/next //head is the nextest segment
var/stomachProcessProbability = 50
var/digestionProbability = 20
var/flatPlasmaValue = 5 //flat plasma amount given for non-items
var/atom/currentlyEating //what the worm is currently eating
var/eatingDuration = 0 //how long he's been eating it for
head
name = "space worm head"
icon_state = "spacewormhead"
icon_living = "spacewormhead"
icon_dead = "spacewormdead"
maxHealth = 20
health = 20
melee_damage_lower = 10
melee_damage_upper = 15
attacktext = "bitten"
animate_movement = SLIDE_STEPS
New(var/location, var/segments = 6)
..()
var/mob/living/simple_animal/space_worm/current = src
for(var/i = 1 to segments)
var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc)
current.Attach(newSegment)
current = newSegment
update_icon()
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
icon_state = "spacewormhead[previous?1:0]"
if(previous)
set_dir(get_dir(previous,src))
else
icon_state = "spacewormheaddead"
Life()
..()
if(next && !(next in view(src,1)))
Detach()
if(stat == DEAD) //dead chunks fall off and die immediately
if(previous)
previous.Detach()
if(next)
Detach(1)
if(prob(stomachProcessProbability))
ProcessStomach()
update_icon()
return
Destroy() //if a chunk a destroyed, make a new worm out of the split halves
if(previous)
previous.Detach()
..()
Move()
var/attachementNextPosition = loc
if(..())
if(previous)
previous.Move(attachementNextPosition)
update_icon()
Bump(atom/obstacle)
if(currentlyEating != obstacle)
currentlyEating = obstacle
eatingDuration = 0
if(!AttemptToEat(obstacle))
eatingDuration++
else
currentlyEating = null
eatingDuration = 0
return
update_icon() //only for the sake of consistency with the other update icon procs
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
if(previous) //midsection
icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below
else //tail
icon_state = "spacewormtail"
set_dir(get_dir(src,next)) //next will always be present since it's not a head and if it's dead, it goes in the other if branch
else
icon_state = "spacewormdead"
return
proc/AttemptToEat(var/atom/target)
if(istype(target,/turf/simulated/wall))
var/turf/simulated/wall/W = target
if((!W.reinf_material && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
W.dismantle_wall()
return 1
else if(istype(target,/atom/movable))
if(istype(target,/mob) || eatingDuration >= 50) //5 ticks to eat stuff like airlocks
var/atom/movable/objectOrMob = target
contents += objectOrMob
return 1
return 0
proc/Attach(var/mob/living/simple_animal/space_worm/attachement)
if(!attachement)
return
previous = attachement
attachement.next = src
return
proc/Detach(die = 0)
var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0)
var/mob/living/simple_animal/space_worm/newHeadPrevious = previous
previous = null //so that no extra heads are spawned
newHead.Attach(newHeadPrevious)
if(die)
newHead.death()
qdel(src)
proc/ProcessStomach()
for(var/atom/movable/stomachContent in contents)
if(prob(digestionProbability))
if(istype(stomachContent,/obj/item/stack)) //converts to plasma, keeping the stack value
if(!istype(stomachContent,/obj/item/stack/material/phoron))
var/obj/item/stack/oldStack = stomachContent
new /obj/item/stack/material/phoron(src, oldStack.get_amount())
qdel(oldStack)
continue
else if(istype(stomachContent,/obj/item)) //converts to plasma, keeping the w_class
var/obj/item/oldItem = stomachContent
new /obj/item/stack/material/phoron(src, oldItem.w_class)
qdel(oldItem)
continue
else
new /obj/item/stack/material/phoron(src, flatPlasmaValue) //just flat amount
qdel(stomachContent)
continue
if(previous)
for(var/atom/movable/stomachContent in contents) //transfer it along the digestive tract
previous.contents += stomachContent
else
for(var/atom/movable/stomachContent in contents) //or poop it out
loc.contents += stomachContent
return
@@ -158,7 +158,7 @@
if(host.mind)
borers.remove_antagonist(host.mind)
src.loc = get_turf(host)
src.forceMove(get_turf(host))
reset_view(null)
machine = null
@@ -105,7 +105,7 @@
src.host = M
src.host.status_flags |= PASSEMOTES
src.loc = M
src.forceMove(M)
//Update their traitor status.
if(host.mind)
@@ -131,7 +131,7 @@
qdel(animation)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
S.loc = src //put shade in stone
S.forceMove(src) //put shade in stone
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = 0//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
@@ -167,7 +167,7 @@
U << "<span class='danger'>Capture failed!</span>: The soul stone has already been imprinted with [src.imprinted]'s mind!"
return
T.loc = src //put shade in stone
T.forceMove(src) //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
@@ -1,223 +0,0 @@
#define SPINNING_WEB 1
#define LAYING_EGGS 2
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
//basic spider mob, these generally guard nests
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and black, it makes you shudder to look at it. This one has deep red eyes."
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
speak_emote = list("chitters")
emote_hear = list("chitters")
speak_chance = 5
turns_per_move = 5
see_in_dark = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
stop_automated_movement_when_pulled = 0
maxHealth = 200
health = 200
melee_damage_lower = 15
melee_damage_upper = 20
heat_damage_per_tick = 20
cold_damage_per_tick = 20
var/poison_per_bite = 5
var/poison_chance = 10
var/poison_type = "spidertoxin"
faction = "spiders"
var/busy = 0
pass_flags = PASSTABLE
move_to_delay = 6
speed = 3
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
desc = "Furry and black, it makes you shudder to look at it. This one has brilliant green eyes."
icon_state = "nurse"
icon_living = "nurse"
icon_dead = "nurse_dead"
maxHealth = 40
health = 40
melee_damage_lower = 5
melee_damage_upper = 10
poison_per_bite = 7
var/atom/cocoon_target
poison_type = "stoxin"
var/fed = 0
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
icon_state = "hunter"
icon_living = "hunter"
icon_dead = "hunter_dead"
maxHealth = 120
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
poison_per_bite = 5
move_to_delay = 4
/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent)
get_light_and_color(parent)
..()
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
. = ..()
if(isliving(.))
var/mob/living/L = .
if(L.reagents)
L.reagents.add_reagent(poison_type, poison_per_bite)
if(prob(poison_chance))
L << "<span class='warning'>You feel a tiny prick.</span>"
L.reagents.add_reagent(poison_type, poison_per_bite)
/mob/living/simple_animal/hostile/giant_spider/nurse/AttackingTarget()
. = ..()
if(ishuman(.))
var/mob/living/carbon/human/H = .
if(prob(5))
var/obj/item/organ/external/O = pick(H.organs)
if(!(O.robotic >= ORGAN_ROBOT))
var/eggcount
for(var/obj/I in O.implants)
if(istype(I, /obj/effect/spider/eggcluster))
eggcount ++
if(!eggcount)
var/eggs = PoolOrNew(/obj/effect/spider/eggcluster/small, list(O, src))
O.implants += eggs
H << "<span class='warning'>The [src] injects something into your [O.name]!</span>"
/mob/living/simple_animal/hostile/giant_spider/Life()
..()
if(!stat)
if(stance == STANCE_IDLE)
//1% chance to skitter madly away
if(!busy && prob(1))
/*var/list/move_targets = list()
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
walk_to(src, pick(orange(20, src)), 1, move_to_delay)
spawn(50)
stop_automated_movement = 0
walk(src,0)
/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C)
spawn(100)
if(busy == MOVING_TO_TARGET)
if(cocoon_target == C && get_dist(src,cocoon_target) > 1)
cocoon_target = null
busy = 0
stop_automated_movement = 0
/mob/living/simple_animal/hostile/giant_spider/nurse/Life()
..()
if(!stat)
if(stance == STANCE_IDLE)
var/list/can_see = view(src, 10)
//30% chance to stop wandering and do something
if(!busy && prob(30))
//first, check for potential food nearby to cocoon
for(var/mob/living/C in can_see)
if(C.stat)
cocoon_target = C
busy = MOVING_TO_TARGET
walk_to(src, C, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(C)
return
//second, spin a sticky spiderweb on this tile
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
busy = SPINNING_WEB
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance.</span>")
stop_automated_movement = 1
spawn(40)
if(busy == SPINNING_WEB)
new /obj/effect/spider/stickyweb(src.loc)
busy = 0
stop_automated_movement = 0
else
//third, lay an egg cluster there
var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
if(!E && fed > 0)
busy = LAYING_EGGS
src.visible_message("<span class='notice'>\The [src] begins to lay a cluster of eggs.</span>")
stop_automated_movement = 1
spawn(50)
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
PoolOrNew(/obj/effect/spider/eggcluster, list(loc, src))
fed--
busy = 0
stop_automated_movement = 0
else
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
for(var/obj/O in can_see)
if(O.anchored)
continue
if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, O, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(O)
else if(busy == MOVING_TO_TARGET && cocoon_target)
if(get_dist(src, cocoon_target) <= 1)
busy = SPINNING_COCOON
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance around \the [cocoon_target].</span>")
stop_automated_movement = 1
walk(src,0)
spawn(50)
if(busy == SPINNING_COCOON)
if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
for(var/mob/living/M in C.loc)
if(istype(M, /mob/living/simple_animal/hostile/giant_spider))
continue
large_cocoon = 1
fed++
src.visible_message("<span class='warning'>\The [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.</span>")
M.loc = C
C.pixel_x = M.pixel_x
C.pixel_y = M.pixel_y
break
for(var/obj/item/I in C.loc)
I.loc = C
for(var/obj/structure/S in C.loc)
if(!S.anchored)
S.loc = C
large_cocoon = 1
for(var/obj/machinery/M in C.loc)
if(!M.anchored)
M.loc = C
large_cocoon = 1
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
busy = 0
stop_automated_movement = 0
else
busy = 0
stop_automated_movement = 0
#undef SPINNING_WEB
#undef LAYING_EGGS
#undef MOVING_TO_TARGET
#undef SPINNING_COCOON
@@ -1,8 +0,0 @@
/mob/living/simple_animal/hostile
faction = "hostile"
break_stuff_probability = 10
stop_automated_movement_when_pulled = 0
destroy_surroundings = 1
a_intent = I_HURT
hostile = 1
@@ -1,49 +0,0 @@
/mob/living/simple_animal/hostile/retaliate
var/list/enemies = list()
/mob/living/simple_animal/hostile/retaliate/Found(var/atom/A)
if(isliving(A))
var/mob/living/L = A
if(!L.stat)
stance = STANCE_ATTACK
return L
else
enemies -= L
else if(istype(A, /obj/mecha))
var/obj/mecha/M = A
if(M.occupant)
stance = STANCE_ATTACK
return A
/mob/living/simple_animal/hostile/retaliate/ListTargets()
if(!enemies.len)
return list()
var/list/see = ..()
see &= enemies // Remove all entries that aren't in enemies
return see
/mob/living/simple_animal/hostile/retaliate/proc/Retaliate()
..()
var/list/around = view(src, 7)
for(var/atom/movable/A in around)
if(A == src)
continue
if(isliving(A))
var/mob/living/M = A
if(!attack_same && M.faction != faction)
enemies |= M
else if(istype(A, /obj/mecha))
var/obj/mecha/M = A
if(M.occupant)
enemies |= M
enemies |= M.occupant
for(var/mob/living/simple_animal/hostile/retaliate/H in around)
if(!attack_same && !H.attack_same && H.faction == faction)
H.enemies |= enemies
return 0
/mob/living/simple_animal/hostile/retaliate/adjustBruteLoss(var/damage)
..(damage)
Retaliate()
@@ -1,39 +1,47 @@
/mob/living/simple_animal/hostile/retaliate/clown
name = "clown"
desc = "A denizen of clown planet"
icon_state = "clown"
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
speak = list("HONK", "Honk!", "Welcome to clown planet!")
emote_see = list("honks")
speak_chance = 1
a_intent = I_HURT
stop_automated_movement_when_pulled = 0
maxHealth = 75
health = 75
speed = -1
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "attacked"
attack_sound = 'sound/items/bikehorn.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
minbodytemp = 270
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
unsuitable_atoms_damage = 10
/mob/living/simple_animal/hostile/clown
name = "clown"
desc = "A denizen of clown planet"
icon_state = "clown"
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
faction = "clown"
maxHealth = 75
health = 75
speed = -1
move_to_delay = 2
run_at_them = 0
cooperative = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "attacked"
attack_sound = 'sound/items/bikehorn.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
minbodytemp = 270
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
unsuitable_atoms_damage = 10
speak_chance = 1
speak = list("HONK", "Honk!", "Welcome to clown planet!")
emote_see = list("honks")
@@ -5,16 +5,23 @@
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
wander = 0
stop_automated_movement = 1
universal_speak = 1
speak_chance = 1
turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
speak_chance = 1
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/list/insults = list(
"Man you suck",
"You look like the most retarded douche around",
@@ -32,22 +39,15 @@
"Say \"what\" again. Say \"what\" again. I dare you. I double-dare you, motherfucker. Say \"what\" one more goddamn time.",
"Ezekiel 25:17 ,The path of the righteous man is beset on all sides by the iniquities of the selfish and the tyranny of evil men. Blessed is he who in the name of charity and good will shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children. And I will strike down upon thee with great vengeance and furious anger those who attempt to poison and destroy my brothers. And you will know my name is the Lord... when I lay my vengeance upon thee.",
"Did you notice a sign out in front of my house that said \"Dead Nigger Storage\"?")
stop_automated_movement = 1
/mob/living/simple_animal/head/Life()
if(stat == DEAD)
if(health > 0)
icon_state = icon_living
stat = CONSCIOUS
density = 1
return
else if(health < 1)
Die()
else if(health > maxHealth)
health = maxHealth
. = ..()
if(!. || ai_inactive) return
for(var/mob/A in viewers(world.view,src))
if(A.ckey)
say_something(A)
/mob/living/simple_animal/head/proc/say_something(mob/A)
if(prob(85))
return
@@ -6,25 +6,34 @@
icon_state = "kobold_idle"
icon_living = "kobold_idle"
icon_dead = "kobold_dead"
//speak = list("You no take candle!","Ooh, pretty shiny.","Me take?","Where gold here...","Me likey.")
speak_emote = list("mutters","hisses","grumbles")
emote_hear = list("mutters under it's breath.","grumbles.", "yips!")
emote_see = list("looks around suspiciously.", "scratches it's arm.","putters around a bit.")
speak_chance = 15
run_at_them = 0
cooperative = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
minbodytemp = 250
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
speak_chance = 5
speak = list("You no take candle!","Ooh, pretty shiny.","Me take?","Where gold here...","Me likey.")
speak_emote = list("mutters","hisses","grumbles")
emote_hear = list("mutters under it's breath.","grumbles.", "yips!")
emote_see = list("looks around suspiciously.", "scratches it's arm.","putters around a bit.")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey
/mob/living/simple_animal/kobold/Life()
..()
if(prob(15) && turns_since_move && !stat)
. = ..()
if(!.) return
if(prob(5))
flick("kobold_act",src)
/mob/living/simple_animal/kobold/Move(var/dir)
@@ -0,0 +1,94 @@
/mob/living/simple_animal/hostile/mecha
name = "syndicate gygax"
desc = "Well that's forboding."
icon = 'icons/mecha/mecha.dmi'
icon_state = "darkgygax"
icon_living = "darkgygax"
icon_dead = "darkgygax-broken"
faction = "syndicate"
maxHealth = 300
health = 300
speed = 7
move_to_delay = 8
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "taps on"
response_disarm = "knocks on"
response_harm = "uselessly hits"
harm_intent_damage = 0
melee_damage_lower = 35
melee_damage_upper = 35
attacktext = "slashed"
attack_sound = 'sound/weapons/bladeslice.ogg'
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 = 0
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/beam
projectilesound = 'sound/weapons/laser.ogg'
speak_chance = 1
speak = list("Know what we need? More meatshields.",
"Glad I finally got a mech.",
"I'll stomp those NanoTrasen dogs into paste.",
"Glad I didn't become a line chef.",
"This anti-fog visor is nice...",
"Did I refill the air tank?")
emote_hear = list("humms ominously","whirrs softly","grinds a gear")
emote_see = list("looks around the area","turns from side to side")
say_understood = list()
say_cannot = list()
say_maybe_target = list("Just my sensors?","Detecting something?","Is that...?","What was that?")
say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
reactions = list()
var/datum/effect/effect/system/spark_spread/sparks
var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark
/mob/living/simple_animal/hostile/mecha/New()
..()
sparks = new (src)
sparks.set_up(3, 1, src)
/mob/living/simple_animal/hostile/mecha/Destroy()
qdel(sparks)
..()
/mob/living/simple_animal/hostile/mecha/Life()
. = ..()
if(!.) return
if((health < maxHealth*0.3) && prob(10))
sparks.start()
/mob/living/simple_animal/hostile/mecha/bullet_act()
..()
sparks.start()
/mob/living/simple_animal/hostile/mecha/death()
..(0,"is explodes!")
sparks.start()
explosion(get_turf(src), 0, 0, 1, 3)
qdel(src)
new /obj/effect/decal/mecha_wreckage/gygax/dark(get_turf(src))
/mob/living/simple_animal/hostile/mecha/Move()
..()
playsound(src,'sound/mecha/mechstep.ogg',40,1)
@@ -1,56 +1,66 @@
/mob/living/simple_animal/hostile/pirate
name = "Pirate"
desc = "Does what he wants cause a pirate is free."
icon_state = "piratemelee"
icon_living = "piratemelee"
icon_dead = "piratemelee_dead"
speak_chance = 0
turns_per_move = 5
response_help = "pushes"
response_disarm = "shoves"
response_harm = "hits"
speed = 4
stop_automated_movement_when_pulled = 0
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "slashed"
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
var/corpse = /obj/effect/landmark/mobcorpse/pirate
var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate
faction = "pirate"
/mob/living/simple_animal/hostile/pirate/ranged
name = "Pirate Gunner"
icon_state = "pirateranged"
icon_living = "pirateranged"
icon_dead = "piratemelee_dead"
projectilesound = 'sound/weapons/laser.ogg'
ranged = 1
projectiletype = /obj/item/projectile/beam
corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
weapon1 = /obj/item/weapon/gun/energy/laser
/mob/living/simple_animal/hostile/pirate/death()
..()
if(corpse)
new corpse (src.loc)
if(weapon1)
new weapon1 (src.loc)
qdel(src)
/mob/living/simple_animal/hostile/pirate
name = "Pirate"
desc = "Does what he wants cause a pirate is free."
icon_state = "piratemelee"
icon_living = "piratemelee"
icon_dead = "piratemelee_dead"
faction = "pirate"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "pushes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "slashed"
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
loot_list = list(/obj/item/weapon/melee/energy/sword/pirate = 100)
var/corpse = /obj/effect/landmark/mobcorpse/pirate
/mob/living/simple_animal/hostile/pirate/ranged
name = "Pirate Gunner"
icon_state = "pirateranged"
icon_living = "pirateranged"
icon_dead = "piratemelee_dead"
ranged = 1
projectiletype = /obj/item/projectile/beam
projectilesound = 'sound/weapons/laser.ogg'
loot_list = list(/obj/item/weapon/gun/energy/laser = 100)
corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
/mob/living/simple_animal/hostile/pirate/death()
..()
if(corpse)
new corpse (src.loc)
qdel(src)
return
@@ -1,55 +1,66 @@
/mob/living/simple_animal/hostile/russian
name = "russian"
desc = "For the Motherland!"
icon_state = "russianmelee"
icon_living = "russianmelee"
icon_dead = "russianmelee_dead"
icon_gib = "syndicate_gib"
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = 4
stop_automated_movement_when_pulled = 0
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "punched"
a_intent = I_HURT
var/corpse = /obj/effect/landmark/mobcorpse/russian
var/weapon1 = /obj/item/weapon/material/knife
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
faction = "russian"
status_flags = CANPUSH
/mob/living/simple_animal/hostile/russian/ranged
icon_state = "russianranged"
icon_living = "russianranged"
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba
ranged = 1
projectiletype = /obj/item/projectile/bullet
projectilesound = 'sound/weapons/Gunshot.ogg'
casingtype = /obj/item/ammo_casing/spent
/mob/living/simple_animal/hostile/russian/death()
..()
if(corpse)
new corpse (src.loc)
if(weapon1)
new weapon1 (src.loc)
qdel(src)
return
/mob/living/simple_animal/hostile/russian
name = "russian"
desc = "For the Motherland!"
icon_state = "russianmelee"
icon_living = "russianmelee"
icon_dead = "russianmelee_dead"
icon_gib = "syndicate_gib"
faction = "russian"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
status_flags = CANPUSH
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "punched"
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
loot_list = list(/obj/item/weapon/material/knife = 100)
var/corpse = /obj/effect/landmark/mobcorpse/russian
/mob/living/simple_animal/hostile/russian/ranged
icon_state = "russianranged"
icon_living = "russianranged"
ranged = 1
projectiletype = /obj/item/projectile/bullet
casingtype = /obj/item/ammo_casing/spent
projectilesound = 'sound/weapons/Gunshot.ogg'
loot_list = list(/obj/item/weapon/gun/projectile/revolver/mateba = 100)
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
/mob/living/simple_animal/hostile/russian/death()
..()
if(corpse)
new corpse (src.loc)
qdel(src)
return
@@ -1,163 +1,192 @@
/mob/living/simple_animal/hostile/syndicate
name = "\improper Syndicate operative"
desc = "Death to the Company."
icon_state = "syndicate"
icon_living = "syndicate"
icon_dead = "syndicate_dead"
icon_gib = "syndicate_gib"
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = 4
stop_automated_movement_when_pulled = 0
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "punched"
a_intent = I_HURT
var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
var/weapon1
var/weapon2
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
environment_smash = 1
faction = "syndicate"
status_flags = CANPUSH
/mob/living/simple_animal/hostile/syndicate/death()
..()
if(corpse)
new corpse (src.loc)
if(weapon1)
new weapon1 (src.loc)
if(weapon2)
new weapon2 (src.loc)
qdel(src)
return
///////////////Sword and shield////////////
/mob/living/simple_animal/hostile/syndicate/melee
melee_damage_lower = 20
melee_damage_upper = 25
icon_state = "syndicatemelee"
icon_living = "syndicatemelee"
weapon1 = /obj/item/weapon/melee/energy/sword/red
weapon2 = /obj/item/weapon/shield/energy
attacktext = "slashed"
status_flags = 0
/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(prob(80))
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
health -= damage
visible_message("\red \b [src] has been attacked with the [O] by [user]. ")
else
visible_message("\red \b [src] blocks the [O] with its shield! ")
//user.do_attack_animation(src)
else
usr << "\red This weapon is ineffective, it does no damage."
visible_message("\red [user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
if(prob(65))
src.health -= Proj.damage
else
visible_message("\red <B>[src] blocks [Proj] with its shield!</B>")
return 0
/mob/living/simple_animal/hostile/syndicate/melee/space
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
icon_state = "syndicatemeleespace"
icon_living = "syndicatemeleespace"
name = "Syndicate Commando"
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
speed = 0
/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/syndicate/ranged
ranged = 1
rapid = 1
icon_state = "syndicateranged"
icon_living = "syndicateranged"
casingtype = /obj/item/ammo_casing/spent
projectilesound = 'sound/weapons/Gunshot_light.ogg'
projectiletype = /obj/item/projectile/bullet/pistol/medium
weapon1 = /obj/item/weapon/gun/projectile/automatic/c20r
/mob/living/simple_animal/hostile/syndicate/ranged/space
icon_state = "syndicaterangedpsace"
icon_living = "syndicaterangedpsace"
name = "Syndicate Commando"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
speed = 0
/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/viscerator
name = "viscerator"
desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
icon = 'icons/mob/critter.dmi'
icon_state = "viscerator_attack"
icon_living = "viscerator_attack"
pass_flags = PASSTABLE
health = 15
maxHealth = 15
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "cut"
attack_sound = 'sound/weapons/bladeslice.ogg'
faction = "syndicate"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
/mob/living/simple_animal/hostile/viscerator/death()
..(null,"is smashed into pieces!")
qdel(src)
/mob/living/simple_animal/hostile/syndicate
name = "syndicate operative"
desc = "Death to the Company."
icon_state = "syndicate"
icon_living = "syndicate"
icon_dead = "syndicate_dead"
icon_gib = "syndicate_gib"
faction = "syndicate"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
status_flags = CANPUSH
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 15
environment_smash = 1
attacktext = "punched"
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
speak_chance = 1
speak = list("Fuckin' NT, man.",
"When are we gonna get out of this chicken-shit outfit?",
"Wish I had better equipment...",
"I knew I should have been a line chef...",
"Fuckin' helmet keeps fogging up.",
"Anyone else smell that?")
emote_hear = list("sniffs","coughs","taps his foot")
emote_see = list("looks around","checks his equipment")
say_understood = list()
say_cannot = list()
say_maybe_target = list("What's that?","Is someone there?","Is that...?","Hmm?")
say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
reactions = list("Hey guys, you ready?" = "Fuck yeah!")
var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
/mob/living/simple_animal/hostile/syndicate/death()
..()
if(corpse)
new corpse (src.loc)
qdel(src)
return
///////////////Sword and shield////////////
/mob/living/simple_animal/hostile/syndicate/melee
icon_state = "syndicatemelee"
icon_living = "syndicatemelee"
melee_damage_lower = 20
melee_damage_upper = 25
attacktext = "slashed"
status_flags = 0
loot_list = list(/obj/item/weapon/melee/energy/sword/red = 100, /obj/item/weapon/shield/energy = 100)
/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(prob(20))
visible_message("<span class='danger'>\The [src] blocks \the [O] with its shield!</span>")
if(user)
react_to_attack(user)
return
else
..()
else
usr << "<span class='warning'>This weapon is ineffective, it does no damage.</span>"
visible_message("<span class='warning'>\The [user] gently taps [src] with \the [O].</span>")
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
if(prob(35))
visible_message("\red <B>[src] blocks [Proj] with its shield!</B>")
if(Proj.firer)
react_to_attack(Proj.firer)
return
else
..()
/mob/living/simple_animal/hostile/syndicate/melee/space
name = "syndicate commando"
icon_state = "syndicatemeleespace"
icon_living = "syndicatemeleespace"
speed = 0
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/syndicate/ranged
icon_state = "syndicateranged"
icon_living = "syndicateranged"
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/bullet/pistol/medium
casingtype = /obj/item/ammo_casing/spent
projectilesound = 'sound/weapons/Gunshot_light.ogg'
loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100)
/mob/living/simple_animal/hostile/syndicate/ranged/space
name = "syndicate sommando"
icon_state = "syndicaterangedpsace"
icon_living = "syndicaterangedpsace"
speed = 0
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/viscerator
name = "viscerator"
desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
icon = 'icons/mob/critter.dmi'
icon_state = "viscerator_attack"
icon_living = "viscerator_attack"
faction = "syndicate"
maxHealth = 15
health = 15
pass_flags = PASSTABLE
melee_damage_lower = 15
melee_damage_upper = 15
attack_sound = 'sound/weapons/bladeslice.ogg'
attacktext = "cut"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
/mob/living/simple_animal/hostile/viscerator/death()
..(null,"is smashed into pieces!")
qdel(src)
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -341,7 +341,7 @@
if ((stat != 2 || !( ticker )))
usr << "<span class='notice'><B>You must be dead to use this!</B></span>"
return
if (ticker.mode.deny_respawn) //BS12 EDIT
if (ticker.mode && ticker.mode.deny_respawn) //BS12 EDIT
usr << "<span class='notice'>Respawn is disabled for this roundtype.</span>"
return
else
@@ -706,12 +706,13 @@
/mob/proc/facedir(var/ndir)
if(!canface() || client.moving || world.time < client.move_delay)
if(!canface() || (client && (client.moving || (world.time < client.move_delay))))
return 0
set_dir(ndir)
if(buckled && buckled.buckle_movable)
buckled.set_dir(ndir)
client.move_delay += movement_delay()
if(client)
client.move_delay += movement_delay()
return 1
+1 -1
View File
@@ -535,7 +535,7 @@ proc/is_blind(A)
if(. == SAFE_PERP)
return SAFE_PERP
if(!istype(src, /mob/living/simple_animal/hostile/retaliate/goat))
if(!istype(src, /mob/living/simple_animal/retaliate/goat))
threatcount += 4
return threatcount
+2
View File
@@ -44,6 +44,8 @@
usr << "<span class='danger'>You have deadchat muted.</span>"
return
message = say_emphasis(message)
say_dead_direct("[pick("complains","moans","whines","laments","blubbers")], <span class='message'>\"[message]\"</span>", src)
/mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null)
+1 -1
View File
@@ -304,7 +304,7 @@
return 1
if(ispath(MP, /mob/living/simple_animal/shade))
return 1
if(ispath(MP, /mob/living/simple_animal/tomato))
if(ispath(MP, /mob/living/simple_animal/hostile/tomato))
return 1
if(ispath(MP, /mob/living/simple_animal/mouse))
return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak)
+6 -2
View File
@@ -281,9 +281,13 @@ var/list/organ_cache = list()
return
switch (severity)
if (1)
take_damage(5)
take_damage(rand(6,12))
if (2)
take_damage(2)
take_damage(rand(4,8))
if (3)
take_damage(rand(3,6))
if (4)
take_damage(rand(1,4))
/obj/item/organ/proc/removed(var/mob/living/user)
+13 -5
View File
@@ -102,11 +102,19 @@
/obj/item/organ/external/emp_act(severity)
if(!(robotic >= ORGAN_ROBOT))
return
var/burn_damage = 0
switch (severity)
if (1)
take_damage(8)
burn_damage += rand(8, 13)
if (2)
take_damage(4)
burn_damage += rand(6, 9)
if(3)
burn_damage += rand(4, 7)
if(4)
burn_damage += rand(1, 5)
if(burn_damage)
take_damage(0, burn_damage)
/obj/item/organ/external/attack_self(var/mob/living/user)
if(!contents.len)
@@ -243,12 +251,12 @@
return (vital || (robotic >= ORGAN_ROBOT) || brute_dam + burn_dam + additional_damage < max_damage)
/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
brute = round(brute * brute_mod, 0.1)
burn = round(burn * burn_mod, 0.1)
if((brute <= 0) && (burn <= 0))
return 0
brute *= brute_mod
burn *= burn_mod
// High brute damage or sharp objects may damage internal organs
if(internal_organs && (brute_dam >= max_damage || (((sharp && brute >= 5) || brute >= 10) && prob(5))))
// Damage an internal organ
+27 -20
View File
@@ -70,30 +70,30 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
parts = list(BP_HEAD)
monitor_styles = standard_monitor_styles
/datum/robolimb/hesphiastos
company = "Hesphiastos"
/datum/robolimb/hephaestus
company = "Hephaestus"
desc = "This limb has a militaristic black and green casing with gold stripes."
icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_main.dmi'
icon = 'icons/mob/human_races/cyberlimbs/hephaestus/hephaestus_main.dmi'
unavailable_to_build = 1
/datum/robolimb/hesphiastos_alt1
company = "Hesphiastos - Frontier"
desc = "A rugged prosthetic head featuring the standard Hesphiastos theme, a visor and an external display."
icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_alt1.dmi'
/datum/robolimb/hephaestus_alt1
company = "Hephaistos - Frontier"
desc = "A rugged prosthetic head featuring the standard Hephaestus theme, a visor and an external display."
icon = 'icons/mob/human_races/cyberlimbs/hephaestus/hephaestus_alt1.dmi'
unavailable_to_build = 1
parts = list(BP_HEAD)
monitor_styles = "blank=hesphiastos_alt_off;\
pink=hesphiastos_alt_pink;\
orange=hesphiastos_alt_orange;\
goggles=hesphiastos_alt_goggles;\
scroll=hesphiastos_alt_scroll;\
rgb=hesphiastos_alt_rgb;\
rainbow=hesphiastos_alt_rainbow"
monitor_styles = "blank=hephaestus_alt_off;\
pink=hephaestus_alt_pink;\
orange=hephaestus_alt_orange;\
goggles=hephaestus_alt_goggles;\
scroll=hephaestus_alt_scroll;\
rgb=hephaestus_alt_rgb;\
rainbow=hephaestus_alt_rainbow"
/datum/robolimb/hesphiastos_monitor
company = "Hesphiastos Monitor"
desc = "Hesphiastos' unique spin on a popular prosthetic head model. It looks rugged and sturdy."
icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_monitor.dmi'
/datum/robolimb/hephaistos_monitor
company = "Hephaestus Monitor"
desc = "Hephaestus' unique spin on a popular prosthetic head model. It looks rugged and sturdy."
icon = 'icons/mob/human_races/cyberlimbs/hephaestus/hephaestus_monitor.dmi'
unavailable_to_build = 1
parts = list(BP_HEAD)
monitor_styles = standard_monitor_styles
@@ -112,6 +112,13 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
unavailable_to_build = 1
parts = list(BP_HEAD)
/datum/robolimb/morpheus_alt2
company = "Morpheus - Skeleton Crew"
desc = "This limb is simple and functional; it's basically just a case for a brain."
icon = 'icons/mob/human_races/cyberlimbs/morpheus/morpheus_alt2.dmi'
unavailable_to_build = 1
parts = list(BP_HEAD)
/datum/robolimb/veymed
company = "Vey-Med"
desc = "This high quality limb is nearly indistinguishable from an organic one."
@@ -183,8 +190,8 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
/obj/item/weapon/disk/limb/bishop
company = "Bishop"
/obj/item/weapon/disk/limb/hesphiastos
company = "Hesphiastos"
/obj/item/weapon/disk/limb/hephaestus
company = "Hephaestus"
/obj/item/weapon/disk/limb/morpheus
company = "Morpheus"
-1
View File
@@ -1,7 +1,6 @@
/obj/item/organ/internal/cell
name = "microbattery"
desc = "A small, powerful cell for use in fully prosthetic bodies."
icon = 'icons/obj/power.dmi'
icon_state = "scell"
organ_tag = "cell"
parent_organ = BP_TORSO
+23 -13
View File
@@ -72,25 +72,35 @@ var/datum/planet/sif/planet_sif = null
var/new_brightness = (Interpolate(low_brightness, high_brightness, weight = lerp_weight) ) * weather_light_modifier
var/list/low_color_list = hex2rgb(low_color)
var/low_r = low_color_list[1]
var/low_g = low_color_list[2]
var/low_b = low_color_list[3]
var/new_color = null
if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color)
new_color = weather_holder.current_weather.light_color
else
var/list/low_color_list = hex2rgb(low_color)
var/low_r = low_color_list[1]
var/low_g = low_color_list[2]
var/low_b = low_color_list[3]
var/list/high_color_list = hex2rgb(high_color)
var/high_r = high_color_list[1]
var/high_g = high_color_list[2]
var/high_b = high_color_list[3]
var/list/high_color_list = hex2rgb(high_color)
var/high_r = high_color_list[1]
var/high_g = high_color_list[2]
var/high_b = high_color_list[3]
var/new_r = Interpolate(low_r, high_r, weight = lerp_weight)
var/new_g = Interpolate(low_g, high_g, weight = lerp_weight)
var/new_b = Interpolate(low_b, high_b, weight = lerp_weight)
var/new_r = Interpolate(low_r, high_r, weight = lerp_weight)
var/new_g = Interpolate(low_g, high_g, weight = lerp_weight)
var/new_b = Interpolate(low_b, high_b, weight = lerp_weight)
var/new_color = rgb(new_r, new_g, new_b)
new_color = rgb(new_r, new_g, new_b)
spawn(1)
update_sun_deferred(2, new_brightness, new_color)
/datum/planet/proc/update_sun_deferred(var/new_range, var/new_brightness, var/new_color)
set background = 1
set waitfor = 0
var/i = 0
for(var/turf/simulated/floor/T in outdoor_turfs)
T.set_light(2, new_brightness, new_color)
T.set_light(new_range, new_brightness, new_color)
i++
if(i % 30 == 0)
sleep(1)
+14 -1
View File
@@ -8,6 +8,7 @@
#define WEATHER_HAIL "hail"
#define WEATHER_WINDY "windy"
#define WEATHER_HOT "hot"
#define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on.
/datum/weather_holder
var/datum/planet/our_planet = null
@@ -53,6 +54,8 @@
current_weather.process_effects()
/datum/weather_holder/proc/update_icon_effects()
set background = 1
set waitfor = 0
if(current_weather)
for(var/turf/simulated/floor/T in outdoor_turfs)
if(T.z in our_planet.expected_z_levels)
@@ -86,7 +89,8 @@
WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
WEATHER_RAIN = new /datum/weather/sif/rain(),
WEATHER_STORM = new /datum/weather/sif/storm(),
WEATHER_HAIL = new /datum/weather/sif/hail()
WEATHER_HAIL = new /datum/weather/sif/hail(),
WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon()
)
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
roundstart_weather_chances = list(
@@ -107,6 +111,7 @@
var/temp_high = T20C
var/temp_low = T0C
var/light_modifier = 1.0 // Lower numbers means more darkness.
var/light_color = null // If set, changes how the day/night light looks.
var/transition_chances = list() // Assoc list
var/datum/weather_holder/holder = null
@@ -266,3 +271,11 @@
L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, used_weapon = "hail")
to_chat(L, "<span class='warning'>The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!</span>")
/datum/weather/sif/blood_moon
name = "blood moon"
light_modifier = 0.5
light_color = "#FF0000"
transition_chances = list(
WEATHER_BLOODMOON = 100
)
+6
View File
@@ -97,6 +97,12 @@
if(2)
if(active) toggle_power()
stability -= rand(10,20)
if(3)
if(active) toggle_power()
stability -= rand(8,15)
if(4)
if(active) toggle_power()
stability -= rand(5,10)
..()
return 0
+12 -7
View File
@@ -1193,22 +1193,27 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
/obj/machinery/power/apc/ex_act(severity)
switch(severity)
if(1.0)
if(1)
//set_broken() //now qdel() do what we need
if (cell)
cell.ex_act(1.0) // more lags woohoo
cell.ex_act(1) // more lags woohoo
qdel(src)
return
if(2.0)
if(2)
if (prob(75))
set_broken()
if (cell && prob(50))
cell.ex_act(2)
if(3)
if (prob(50))
set_broken()
if (cell && prob(50))
cell.ex_act(2.0)
if(3.0)
cell.ex_act(3)
if(4)
if (prob(25))
set_broken()
if (cell && prob(25))
cell.ex_act(3.0)
if (cell && prob(50))
cell.ex_act(3)
return
/obj/machinery/power/apc/disconnect_terminal()
+3 -3
View File
@@ -165,7 +165,7 @@
return
if (overcharge_percent >= 140)
if (prob(1))
empulse(src.loc, 3, 8, 1)
empulse(src.loc, 2, 3, 6, 8, 1)
if ((2.4e6+1) to 3.6e6)
if (overcharge_percent >= 115)
if (prob(7))
@@ -174,7 +174,7 @@
return
if (overcharge_percent >= 130)
if (prob(1))
empulse(src.loc, 3, 8, 1)
empulse(src.loc, 2, 3, 6, 8, 1)
if (overcharge_percent >= 150)
if (prob(1))
explosion(src.loc, 0, 1, 3, 5)
@@ -186,7 +186,7 @@
return
if (overcharge_percent >= 125)
if (prob(2))
empulse(src.loc, 4, 10, 1)
empulse(src.loc, 2, 4, 7, 10, 1)
if (overcharge_percent >= 140)
if (prob(1))
explosion(src.loc, 1, 3, 5, 8)
+4 -1
View File
@@ -62,9 +62,12 @@
stat &= BROKEN
if(prob(75)) explode()
if(2)
if(prob(25)) stat &= BROKEN
if(prob(50)) stat &= BROKEN
if(prob(10)) explode()
if(3)
if(prob(25)) stat &= BROKEN
duration = 300
if(4)
if(prob(10)) stat &= BROKEN
duration = 300
+1 -1
View File
@@ -29,7 +29,7 @@
if(current_size >= STAGE_THREE)
var/list/handlist = list(l_hand, r_hand)
for(var/obj/item/hand in handlist)
if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && u_equip(hand))
if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
step_towards(hand, src)
src << "<span class = 'warning'>The [S] pulls \the [hand] from your grip!</span>"
apply_effect(current_size * 3, IRRADIATE)
+18 -18
View File
@@ -298,7 +298,7 @@
if(target && prob(60))
movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one
if(current_size >= 9)//The superlarge one does not care about things in its way
if(current_size >= STAGE_FIVE)//The superlarge one does not care about things in its way
spawn(0)
step(src, movement_dir)
spawn(1)
@@ -319,17 +319,17 @@
var/steps = 0
if(!step)
switch(current_size)
if(1)
if(STAGE_ONE)
steps = 1
if(3)
if(STAGE_TWO)
steps = 3//Yes this is right
if(5)
if(STAGE_THREE)
steps = 3
if(7)
if(STAGE_FOUR)
steps = 4
if(9)
if(STAGE_FIVE)
steps = 5
if(11)
if(STAGE_SUPER)
steps = 6
else
steps = step
@@ -397,7 +397,7 @@
mezzer()
else
return 0
if(current_size == 11)
if(current_size == STAGE_SUPER)
smwave()
return 1
@@ -429,21 +429,21 @@
if(M.stat == CONSCIOUS)
if (istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != 11)
if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != STAGE_SUPER)
H << "<span class=\"notice\">You look directly into The [src.name], good thing you had your protective eyewear on!</span>"
return
else
H << "<span class=\"warning\">You look directly into The [src.name], but your eyewear does absolutely nothing to protect you from it!</span>"
M << "<span class='danger'>You look directly into The [src.name] and feel [current_size == 11 ? "helpless" : "weak"].</span>"
M << "<span class='danger'>You look directly into The [src.name] and feel [current_size == STAGE_SUPER ? "helpless" : "weak"].</span>"
M.apply_effect(3, STUN)
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='danger'>[] stares blankly at The []!</span>", M, src), 1)
/obj/singularity/proc/emp_area()
if(current_size != 11)
empulse(src, 8, 10)
if(current_size != STAGE_SUPER)
empulse(src, 4, 6, 8, 10)
else
empulse(src, 12, 16)
empulse(src, 12, 14, 16, 18)
/obj/singularity/proc/smwave()
for(var/mob/living/M in view(10, src.loc))
@@ -467,15 +467,15 @@
overlays = 0
move_self = 0
switch (current_size)
if(1)
if(STAGE_ONE)
overlays += image('icons/obj/singularity.dmi',"chain_s1")
if(3)
if(STAGE_TWO)
overlays += image('icons/effects/96x96.dmi',"chain_s3")
if(5)
if(STAGE_THREE)
overlays += image('icons/effects/160x160.dmi',"chain_s5")
if(7)
if(STAGE_FOUR)
overlays += image('icons/effects/224x224.dmi',"chain_s7")
if(9)
if(STAGE_FIVE)
overlays += image('icons/effects/288x288.dmi',"chain_s9")
/obj/singularity/proc/on_release()

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