diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm
index b571de4c31a..2ff1f55668b 100644
--- a/code/__defines/damage_organs.dm
+++ b/code/__defines/damage_organs.dm
@@ -34,6 +34,8 @@
#define ORGAN_DEAD (1<<6)
#define ORGAN_MUTATED (1<<7)
#define ORGAN_ASSISTED (1<<8)
+#define ORGAN_ADV_ROBOT (1<<9)
+#define ORGAN_PLANT (1<<10)
#define DROPLIMB_EDGE 0
#define DROPLIMB_BLUNT 1
diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm
index 7ba080335f7..2b35801a98c 100644
--- a/code/__defines/items_clothing.dm
+++ b/code/__defines/items_clothing.dm
@@ -63,6 +63,10 @@
#define BLOCKHEADHAIR 0x20 // Hides the user's hair overlay. Leaves facial hair.
#define BLOCKHAIR 0x40 // Hides the user's hair, facial and otherwise.
+//This flag applies to gloves, uniforms, shoes, masks, ear items, glasses
+#define ALWAYSDRAW 32//If set, this item is always rendered even if its slot is hidden by other clothing
+//Note that the item may still not be visible if its sprite is actually covered up.
+
// Slots.
#define slot_back 1
#define slot_wear_mask 2
@@ -97,6 +101,25 @@
#define slot_head_str "slot_head"
#define slot_wear_suit_str "slot_suit"
+//itemstate suffixes. Used for containedsprite worn items
+#define WORN_LHAND "_lh"
+#define WORN_RHAND "_rh"
+#define WORN_LSTORE "_ls"
+#define WORN_RSTORE "_rs"
+#define WORN_SSTORE "_ss"
+#define WORN_LEAR "_le"
+#define WORN_REAR "_re"
+#define WORN_HEAD "_he"
+#define WORN_UNDER "_un"
+#define WORN_SUIT "_su"
+#define WORN_GLOVES "_gl"
+#define WORN_SHOES "_sh"
+#define WORN_EYES "_ey"
+#define WORN_BELT "_be"
+#define WORN_BACK "_ba"
+#define WORN_ID "_id"
+#define WORN_MASK "_ma"
+
// Bitflags for clothing parts.
#define HEAD 0x1
#define FACE 0x2
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 46449f0ff38..e5f1e52c16d 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -50,6 +50,13 @@
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
+//Sound effects toggles
+#define ASFX_AMBIENCE 1
+#define ASFX_FOOTSTEPS 2
+#define ASFX_VOTE 4
+
+#define ASFX_DEFAULT (ASFX_AMBIENCE|ASFX_FOOTSTEPS|ASFX_VOTE)
+
// For secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans.
#define HEALTH_HUD 1 // A simple line rounding the mob's number health.
#define STATUS_HUD 2 // Alive, dead, diseased, etc.
@@ -210,3 +217,28 @@
#define CAPTURE_MODE_REGULAR 0 //Regular polaroid camera mode
#define CAPTURE_MODE_ALL 1 //Admin camera mode
#define CAPTURE_MODE_PARTIAL 3 //Simular to regular mode, but does not do dummy check
+
+//Sound effects toggles
+#define ASFX_AMBIENCE 1
+#define ASFX_FOOTSTEPS 2
+#define ASFX_VOTE 4
+
+//Cargo random stock vars
+//These are used in randomstock.dm
+//And also for generating random loot crates in crates.dm
+#define TOTAL_STOCK 80//The total number of items we'll spawn in cargo stock
+
+
+#define STOCK_UNCOMMON_PROB 23
+//The probability, as a percentage for each item, that we'll choose from the uncommon spawns list
+
+#define STOCK_RARE_PROB 2.8
+//The probability, as a percentage for each item, that we'll choose from the rare spawns list
+
+//If an item is not rare or uncommon, it will be chosen from the common spawns list.
+//So the probability of a common item is 100 - (uncommon + rare)
+
+
+#define STOCK_LARGE_PROB 75
+//Large items are spawned on predetermined locations.
+//For each large spawn marker, this is the chance that we will spawn there
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index d0428cdb6bc..0859792370c 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -62,6 +62,10 @@
#define HEAVY 64
#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL|HEAVY)
+//Types of diona, returned by is_diona
+#define DIONA_NYMPH 1
+#define DIONA_WORKER 2
+
// Robot AI notifications
#define ROBOT_NOTIFICATION_NEW_UNIT 1
#define ROBOT_NOTIFICATION_NEW_NAME 2
@@ -117,7 +121,7 @@
#define MOB_TINY 5
#define MOB_MINISCULE 1
-// Gluttony levels.
+// Gluttony levels.
#define GLUT_TINY 1 // Eat anything tiny and smaller
#define GLUT_SMALLER 2 // Eat anything smaller than we are
#define GLUT_ANYTHING 3 // Eat anything, ever
@@ -141,7 +145,7 @@
#define INCAPACITATION_RESTRAINED 1
#define INCAPACITATION_BUCKLED_PARTIALLY 2
#define INCAPACITATION_BUCKLED_FULLY 4
-#define INCAPACITATION_DISABLED 8
+#define INCAPACITATION_DISABLED 8
#define INCAPACITATION_DEFAULT (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_FULLY|INCAPACITATION_DISABLED)
#define INCAPACITATION_ALL (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_PARTIALLY|INCAPACITATION_BUCKLED_FULLY|INCAPACITATION_DISABLED)
@@ -151,3 +155,11 @@
#define MOB_PULL_SAME 2
#define MOB_PULL_LARGER 3
+//Time of Death constants
+//Used with a list in preference datums to track times of death
+#define CREW "crew" //Used for crewmembers, AI, cyborgs, nymphs, antags
+#define ANIMAL "animal" //Used for mice and any other simple animals
+#define MINISYNTH "minisynth"//Used for drones and pAIs
+
+#define RESPAWN_ANIMAL 3000
+#define RESPAWN_MINISYNTH 6000
diff --git a/code/_helpers/names.dm b/code/_helpers/names.dm
index 430925d5ca7..800a4381403 100644
--- a/code/_helpers/names.dm
+++ b/code/_helpers/names.dm
@@ -47,8 +47,8 @@ var/religion_name = null
return "Tau Ceti"
/proc/commstation_name()
- if (commstation_name)
- return commstation_name
+ if (dock_name)
+ return dock_name
/proc/station_name()
if (station_name)
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 75e690b9259..ee245363000 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -776,7 +776,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
num_contained = 5
contains = list(/obj/item/clothing/suit/armor/vest,
/obj/item/clothing/suit/armor/vest/security,
- /obj/item/clothing/suit/armor/vest/detective,
+ /obj/item/clothing/suit/storage/vest/detective,
/obj/item/clothing/suit/storage/vest/hos,
/obj/item/clothing/suit/storage/vest/pcrc,
/obj/item/clothing/suit/storage/vest/warden,
diff --git a/code/game/gamemodes/antagspawner.dm b/code/game/gamemodes/antagspawner.dm
index 384234d9ad8..e2e2d75dcf7 100644
--- a/code/game/gamemodes/antagspawner.dm
+++ b/code/game/gamemodes/antagspawner.dm
@@ -19,51 +19,29 @@
return
/obj/item/weapon/antag_spawner/borg_tele
- name = "Syndicate Cyborg Teleporter"
+ name = "syndicate cyborg teleporter"
desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field. Due to budget restrictions, it is only possible to deploy a single cyborg at time."
icon = 'icons/obj/device.dmi'
icon_state = "locator"
var/searching = 0
var/askDelay = 10 * 60 * 1
-/obj/item/weapon/antag_spawner/borg_tele/attack_self(mob/user)
- user << "The syndicate robot teleporter is attempting to locate an available cyborg."
- searching = 1
- for(var/mob/dead/observer/O in player_list)
- if(!O.MayRespawn())
- continue
- if(jobban_isbanned(O, "Syndicate") && jobban_isbanned(O, "Mercenary") && jobban_isbanned(O, "Cyborg"))
- continue
- if(O.client)
- if(O.client.prefs.be_special & BE_OPERATIVE)
- question(O.client)
- spawn(600)
- searching = 0
- if(!used)
- user << "Unable to connect to the Syndicate Command. Perhaps you could try again later?"
+/obj/item/weapon/antag_spawner/borg_tele/attack_self(mob/user as mob)
+ if(searching == 0)
+ //Start the process of searching for a new user.
+ user << "You carefully locate the manual activation switch and start the positronic brain's boot process."
+ src.searching = 1
+ var/datum/ghosttrap/G = get_ghost_trap("syndicate cyborg")
+ G.request_player(brainmob, "Someone is requesting a syndicate cyborg.", 60 SECONDS)
+ spawn_antag(G, get_turf(src))
+ spawn(600) reset_search()
-
-/obj/item/weapon/antag_spawner/borg_tele/proc/question(var/client/C)
- spawn(0)
- if(!C)
- return
- var/response = alert(C, "Someone is requesting a syndicate cyborg Would you like to play as one?",
- "Syndicate robot request","Yes", "No", "Never for this round")
- if(response == "Yes")
- response = alert(C, "Are you sure you want to play as a syndicate cyborg?", "Syndicate cyborg request", "Yes", "No")
- if(!C || used || !searching)
- return
- if(response == "Yes")
- spawn_antag(C, get_turf(src))
- else if (response == "Never for this round")
- C.prefs.be_special ^= BE_OPERATIVE
-
-obj/item/weapon/antag_spawner/borg_tele/spawn_antag(client/C, turf/T)
+obj/item/weapon/antag_spawner/borg_tele/spawn_antag(client/G, turf/T)
var/datum/effect/effect/system/spark_spread/S = new /datum/effect/effect/system/spark_spread
S.set_up(4, 1, src)
S.start()
var/mob/living/silicon/robot/H = new /mob/living/silicon/robot/syndicate(T)
- H.key = C.key
+ H.key = G.key
var/newname = sanitizeSafe(input(H,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
if (newname != "")
H.real_name = newname
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 9e6c79660f6..11074bedbab 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -73,6 +73,8 @@
// Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
var/list/sprite_sheets_obj = list()
+ var/icon_override = null //Used to override hardcoded clothing dmis in human clothing pr
+
/obj/item/Destroy()
if(ismob(loc))
var/mob/m = loc
@@ -110,7 +112,7 @@
else
return
-/obj/item/verb/move_to_top()
+/obj/item/verb/move_to_top(obj/item/I in range(1))
set name = "Move To Top"
set category = "Object"
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 588e7ef0495..d3004bef958 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -36,7 +36,7 @@ REAGENT SCANNER
for(var/turf/T in range(1, src.loc) )
- if(!T || !T.intact)
+ if(!T || !T.is_intact())
continue
for(var/obj/O in T.contents)
@@ -50,7 +50,7 @@ REAGENT SCANNER
spawn(10)
if(O)
var/turf/U = O.loc
- if(U.intact)
+ if(U.is_intact())
O.invisibility = 101
O.alpha = 255
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 34d7cdde1ac..ac46f2beaa9 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -41,7 +41,7 @@
name = "robot reclassification board"
desc = "Used to rename a cyborg."
icon_state = "cyborg_upgrade1"
- construction_cost = list(DEFAULT_WALL_MATERIAL=1000)
+// construction_cost = list(DEFAULT_WALL_MATERIAL=1000)
var/heldname = "default name"
/obj/item/borg/upgrade/rename/attack_self(mob/user as mob)
@@ -165,7 +165,7 @@
/obj/item/borg/upgrade/combat
name = "combat cyborg module"
desc = "Unlocks the combat cyborg module"
- construction_cost = list(DEFAULT_WALL_MATERIAL=10000,"glass"=15000,"gold"= 5000,"diamond" = 1000)
+// construction_cost = list(DEFAULT_WALL_MATERIAL=10000,"glass"=15000,"gold"= 5000,"diamond" = 1000)
icon_state = "cyborg_upgrade3"
require_module = 0
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index ba3711fb8b4..c64ab5a1ec8 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -108,6 +108,12 @@
return ..()
/obj/item/weapon/melee/baton/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
+ if(status && (CLUMSY in user.mutations) && prob(50))
+ user << "span class='danger'>You accidentally hit yourself with the [src]!"
+ user.Weaken(30)
+ deductcharge(hitcost)
+ return
+
if(isrobot(target))
return ..()
@@ -141,11 +147,11 @@
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
//stun effects
- L.stun_effect_act(stun, agony, target_zone, src)
+ target.stun_effect_act(stun, agony, hit_zone, src)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
- msg_admin_attack("[key_name(user)] stunned [key_name(L)] with the [src] (JMP)")
-
+ msg_admin_attack("[key_name(user)] stunned [key_name(target)] with the [src] (JMP)")
+
if(status)
deductcharge(hitcost)
@@ -183,7 +189,7 @@
attack_verb = list("poked")
slot_flags = null
baton_color = "#FFDF00"
-
+
/obj/item/weapon/melee/baton/stunrod
name = "stunrod"
desc = "A more-than-lethal weapon used to deal with high threat situations."
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 6721a76e61e..d59d340735d 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -229,3 +229,34 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
contained_sprite = 1
+
+/obj/item/weapon/sord
+ name = "\improper SORD"
+ desc = "This thing is so unspeakably shitty you are having a hard time even holding it."
+ icon_state = "sord"
+ item_state = "sord"
+ slot_flags = SLOT_BELT
+ force = 2
+ throwforce = 1
+ sharp = 1
+ edge = 1
+ w_class = 3
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+
+/obj/item/weapon/banhammer
+ desc = "banhammer"
+ name = "banhammer"
+ icon = 'icons/obj/items.dmi'
+ icon_state = "toyhammer"
+ slot_flags = SLOT_BELT
+ throwforce = 0
+ w_class = 2.0
+ throw_speed = 7
+ throw_range = 15
+ attack_verb = list("banned")
+
+/obj/item/weapon/banhammer/attack(mob/M as mob, mob/user as mob)
+ M << " You have been banned FOR NO REISIN by [user]"
+ user << " You have BANNED [M]"
+ playsound(loc, 'sound/effects/adminhelp.ogg', 15)
diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm
index cd739b769d0..3bad583fe4e 100644
--- a/code/game/objects/random/random.dm
+++ b/code/game/objects/random/random.dm
@@ -479,8 +479,8 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/brandy,\
/obj/item/weapon/reagent_containers/food/drinks/bottle/guinnes,\
/obj/item/weapon/reagent_containers/food/drinks/bottle/drambuie,\
- /obj/item/weapon/reagent_containers/food/drinks/cans/beer,\
- /obj/item/weapon/reagent_containers/food/drinks/cans/ale)
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,\
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale)
/obj/random/melee
name = "random melee weapon"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 1a8b64ad2d7..dfd6659e89d 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -256,7 +256,6 @@
new /obj/item/clothing/under/det(src)
new /obj/item/clothing/under/det/grey(src)
new /obj/item/clothing/under/det/black(src)
- new /obj/item/clothing/under/det/slob(src)
new /obj/item/clothing/suit/storage/det_suit(src)
new /obj/item/clothing/suit/storage/det_suit/technicolor(src)
new /obj/item/clothing/suit/storage/forensics/blue(src)
diff --git a/code/global.dm b/code/global.dm
index 6973eb570f0..9f8970407da 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -33,7 +33,7 @@ var/diary_date_string = null
var/href_logfile = null
var/station_name = "NSS Exodus"
var/station_short = "Exodus"
-var/const/dock_name = "NMSS Odin"
+var/const/dock_name = "NTCC Odin"
var/const/boss_name = "Central Command"
var/const/boss_short = "Centcomm"
var/const/company_name = "NanoTrasen"
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index 1849d3add49..baa96db005e 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -167,7 +167,6 @@ obj/item/clothing/head/det_hat/technicolor/attackby(obj/item/weapon/O as obj, mo
name = "Head of Security hat"
desc = "The hat of the Head of Security. For showing the officers who's in charge."
icon_state = "hoscap"
- flags = HEADCOVERSEYES
armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0)
flags_inv = HIDEEARS
body_parts_covered = 0
diff --git a/code/modules/ghosttrap/trap.dm b/code/modules/ghosttrap/trap.dm
index 0821a637fcd..7cae383b78d 100644
--- a/code/modules/ghosttrap/trap.dm
+++ b/code/modules/ghosttrap/trap.dm
@@ -186,3 +186,14 @@ datum/ghosttrap/drone/transfer_personality(var/mob/candidate, var/mob/living/sil
if(!assess_candidate(candidate))
return 0
drone.transfer_personality(candidate.client)
+
+/***********************************
+* Syndicate Cyborg *
+***********************************/
+/datum/ghosttrap/syndicateborg
+ object = "syndicate cyborg"
+ ban_checks = list("Syndicate","AI","Cyborg")
+ pref_check = "BE_SYNTH"
+ ghost_trap_message = "They are occupying a syndicate cyborg now."
+ ghost_trap_role = "Syndicate Cyborg"
+ can_set_own_name = TRUE
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
index 2d7c6d74d57..2f69744c74a 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
@@ -8,12 +8,24 @@
get_scooped(M)
..()
+//#TODO-MERGE: Test nymph hats
/mob/living/carbon/alien/diona/MouseDrop(atom/over_object)
var/mob/living/carbon/H = over_object
- if(!istype(H) || !Adjacent(H)) return ..()
+ if(!istype(H) || !Adjacent(H))
+ return ..()
+ if(H.a_intent == I_HELP)
+ if(H.species && H.species.name == "Diona" && do_merge(H))
+ return
+ get_scooped(H)
+ return
+ else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
+ hat.loc = get_turf(src)
+ H.put_in_hands(hat)
+ H.visible_message("\The [H] removes \the [src]'s [hat].")
+ hat = null
+ update_icons()
+ else
return ..()
- get_scooped(H, usr)
- return
/mob/living/carbon/alien/diona/attackby(var/obj/item/weapon/W, var/mob/user)
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm b/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm
index 04c8a394a3d..e02926b06dc 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona_nymph.dm
@@ -29,6 +29,7 @@
holder_type = /obj/item/weapon/holder/diona
var/list/sampled_DNA
var/list/language_progress
+ var/obj/item/clothing/head/hat
/mob/living/carbon/alien/diona/ex_act(severity)
if (life_tick < 4)
@@ -294,3 +295,11 @@
update_icons()
return 1
+
+
+/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat)
+ if(hat)
+ return
+ hat = new_hat
+ new_hat.forceMove(src)
+ update_icons()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index acdbda2d244..8d620195d61 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -165,7 +165,7 @@ emp_act
visible_message("\red [user] misses [src] with \the [I]!")
return 0
- var/obj/item/organ/external/affecting = get_organ(target_zone)
+ //var/obj/item/organ/external/affecting = get_organ(target_zone)
if(check_shields(I.force, I, user, target_zone, "the [I.name]"))
return null
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 03786847849..c10cf820b88 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -297,11 +297,6 @@
updatehealth()
return
- var/damage = 0
- radiation -= 1 * RADIATION_SPEED_COEFFICIENT
- if(prob(25))
- damage = 1
-
if (radiation)
//var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs
if(src.is_diona())
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index 4e0d1d4884e..f4007d7f395 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -443,7 +443,7 @@
eyes = "vaurca_eyes" //makes it so that eye colour is not changed when skin colour is.
brute_mod = 0.5 //note to self: remove is_synthetic checks for brmod and burnmod
burn_mod = 1.5 //2x was a bit too much. we'll see how this goes.
- tox_mod = 3 //they're not used to all our weird human bacteria.
+ toxins_mod = 3 //they're not used to all our weird human bacteria.
warning_low_pressure = 50
hazard_low_pressure = 0
ethanol_resistance = 2
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 73ba609d688..d3871827293 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -254,9 +254,6 @@ var/global/list/damage_icon_parts = list()
qdel(stand_icon)
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
- var/g = "male"
- if(gender == FEMALE)
- g = "female"
var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]"
if(lip_style)
@@ -865,7 +862,7 @@ var/global/list/damage_icon_parts = list()
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype()])
standing = image("icon" = wear_suit.sprite_sheets[species.get_bodytype()], "icon_state" = "[wear_suit.icon_state]")
else
- standing = image("icon" = t_icon, "icon_state" = "[wear_suit.icon_state]")
+ standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]")
standing.color = wear_suit.color
if(wear_suit.blood_DNA)
@@ -1072,15 +1069,8 @@ var/global/list/damage_icon_parts = list()
else
t_icon = INV_R_HAND_DEF_ICON
- //apply color
- var/image/standing = image(icon = t_icon, icon_state = t_state)
- standing.color = r_hand.color
+ overlays_standing[R_HAND_LAYER] = image(icon = t_icon, icon_state = t_state)
- overlays_standing[R_HAND_LAYER] = standing
-
- if (handcuffed) drop_r_hand() //this should be moved out of icon code
- else
- overlays_standing[R_HAND_LAYER] = null
if(update_icons) update_icons()
@@ -1121,15 +1111,8 @@ var/global/list/damage_icon_parts = list()
else
t_icon = INV_L_HAND_DEF_ICON
- //apply color
- var/image/standing = image(icon = t_icon, icon_state = t_state)
- standing.color = l_hand.color
+ overlays_standing[L_HAND_LAYER] = image(icon = t_icon, icon_state = t_state)
- overlays_standing[L_HAND_LAYER] = standing
-
- if (handcuffed) drop_l_hand() //This probably should not be here
- else
- overlays_standing[L_HAND_LAYER] = null
if(update_icons) update_icons()
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 6f9e5a5f5d4..3ba7835b92e 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -73,8 +73,9 @@
/mob/living/proc/handle_environment(var/datum/gas_mixture/environment)
return
-/mob/living/proc/handle_stomach()
- return
+// Defined in devour.dm
+// /mob/living/proc/handle_stomach()
+// return
/mob/living/proc/update_pulling()
if(pulling)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index fd96ef731d6..33605a423b4 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -10,6 +10,9 @@
1 - halfblock
2 - fullblock
*/
+#define MOB_FIRE_LIGHT_RANGE 3 //These control the intensity and range of light given off by a mob which is on fire
+#define MOB_FIRE_LIGHT_POWER 2
+
/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/armour_pen = 0, var/absorb_text = null, var/soften_text = null)
if(armour_pen >= 100)
return 0 //might as well just skip the processing
@@ -373,3 +376,6 @@
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,button_number+1)
client.screen += hud_used.hide_actions_toggle
+
+#undef MOB_FIRE_LIGHT_RANGE //These control the intensity and range of light given off by a mob which is on fire
+#undef MOB_FIRE_LIGHT_POWER
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 7392c54ee9a..714cc8f4e95 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -82,6 +82,7 @@ var/list/ai_verbs_default = list(
var/bombing_station = 0 // Set to 1 if station nuke auto-destruct is activated
var/override_CPUStorage = 0 // Bonus/Penalty CPU Storage. For use by admins/testers.
var/override_CPURate = 0 // Bonus/Penalty CPU generation rate. For use by admins/testers.
+ var/list/cameraRecords = list() //For storing what is shown to the cameras
var/datum/ai_icon/selected_sprite // The selected icon set
var/custom_sprite = 0 // Whether the selected icon is custom
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 82df29446f2..18682cde0e4 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -4,7 +4,6 @@
icon_state = "repairbot"
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
- small = 1
pass_flags = PASSTABLE | PASSDOORHATCH
density = 0
mob_size = 1//As a holographic projection, a pAI is massless except for its card device
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index ab083d06d64..66f9d4d4732 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -38,7 +38,6 @@ var/list/mob_hat_cache = list()
local_transmit = 1
possession_candidate = 1
mob_size = 4
- small = 1
can_pull_size = 3
can_pull_mobs = MOB_PULL_SMALLER
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 553ae37ac4f..dbc824be5b5 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -182,17 +182,18 @@ var/global/list/robot_modules = list(
networks = list(NETWORK_MEDICAL)
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
can_be_pushed = 0
+ sprites = list(
+ "Basic" = "Medbot",
+ "Standard" = "surgeon",
+ "Advanced Droid" = "droid-medical",
+ "Needles" = "medicalrobot",
+ "Drone - Medical" = "drone-medical",
+ "Drone - Chemistry" = "drone-chemistry",
+ "Eyebot" = "eyebot-medical"
+ )
/obj/item/weapon/robot_module/medical/general
name = "medical robot module"
- sprites = list(
- "Basic" = "Medbot",
- "Standard" = "surgeon",
- "Advanced Droid" = "droid-medical",
- "Needles" = "medicalrobot",
- "Drone" = "drone-surgery",
- "Eyebot" = "eyebot-medical"
- )
/obj/item/weapon/robot_module/medical/general/New()
..()
@@ -240,15 +241,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/medical/rescue
name = "rescue robot module"
- sprites = list(
- "Basic" = "Medbot",
- "Standard" = "surgeon",
- "Advanced Droid" = "droid-medical",
- "Needles" = "medicalrobot",
- "Drone - Medical" = "drone-medical",
- "Drone - Chemistry" = "drone-chemistry",
- "Eyebot" = "eyebot-medical"
- )
+
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
/obj/item/weapon/robot_module/medical/rescue/New()
@@ -309,7 +302,7 @@ var/global/list/robot_modules = list(
channels = list("Engineering" = 1)
networks = list(NETWORK_ENGINEERING)
subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor)
- supported_upgrades = list(/obj/item/borg/upgrade/rcd)
+ supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
sprites = list(
"Basic" = "Engineering",
"Antique" = "engineerrobot",
@@ -430,7 +423,7 @@ var/global/list/robot_modules = list(
networks = list(NETWORK_SECURITY)
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
can_be_pushed = 0
- supported_upgrades = list(/obj/item/borg/upgrade/tasercooler)
+ supported_upgrades = list(/obj/item/borg/upgrade/tasercooler,/obj/item/robot_parts/robot_component/jetpack)
/obj/item/weapon/robot_module/security/general
sprites = list(
@@ -467,7 +460,7 @@ var/global/list/robot_modules = list(
B.bcell.give(amount)
/obj/item/weapon/robot_module/janitor
- name = "janitorial robot module"
+ name = "custodial robot module"
channels = list("Service" = 1)
sprites = list(
"Basic" = "JanBot2",
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index cbaa17d3ffb..c0846bb3f1c 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -21,7 +21,6 @@
var/last_squealgain = 0// #TODO-FUTURE: Remove from life() once something else is created
pass_flags = PASSTABLE
- small = 1
speak_chance = 5
turns_per_move = 5
see_in_dark = 6
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index b1b923ef5d1..55b7c66e4c5 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -40,7 +40,6 @@
var/obj/item/held_item = null //Storage for single item they can hold.
speed = -1 //Spiderbots gotta go fast.
pass_flags = PASSTABLE | PASSDOORHATCH
- small = 1
speak_emote = list("beeps","clicks","chirps")
/mob/living/simple_animal/spiderbot/New()
@@ -302,4 +301,4 @@
if (!underdoor)
spawn(3)//A slight delay to let us finish walking out from under the door
- layer = initial(layer)
\ No newline at end of file
+ layer = initial(layer)
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 5485b27d416..3308e635310 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -139,7 +139,6 @@
emote_see = list("sniffs the air cautiously","looks around")
emote_hear = list("snuffles")
pass_flags = PASSTABLE
- small = 1
density = 0
mob_size = 3
@@ -172,7 +171,6 @@
icon_dead = "yithian_dead"
icon = 'icons/jungle.dmi'
pass_flags = PASSTABLE
- small = 1
density = 0
mob_size = 2
@@ -184,6 +182,5 @@
icon_dead = "tindalos_dead"
icon = 'icons/jungle.dmi'
pass_flags = PASSTABLE
- small = 1
density = 0
- mob_size = 1.5
\ No newline at end of file
+ mob_size = 1.5
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index 4268d6ad3e6..7f240e8a21e 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -107,7 +107,7 @@
rapid = 1
icon_state = "syndicateranged"
icon_living = "syndicateranged"
- casingtype = /obj/item/ammo_casing/a10mm
+ casingtype = /obj/item/ammo_casing/t40
projectilesound = 'sound/weapons/Gunshot_light.ogg'
projectiletype = /obj/item/projectile/bullet/pistol/medium
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 009509cd111..20807e8cbeb 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -27,6 +27,8 @@
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
var/wander = 1 // Does the mob wander around when idle?
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
+ var/atom/movement_target = null//Thing we're moving towards
+ var/turns_since_scan = 0
//Interaction
var/response_help = "tries to help"
@@ -66,51 +68,109 @@
var/supernatural = 0
var/purge = 0
+
+ //Hunger/feeding vars
+ var/hunger_enabled = 1//If set to 0, a creature ignores hunger
+ var/max_nutrition = 50
+ var/metabolic_factor = 1//A multiplier on how fast nutrition is lost. used to tweak the rates on a per-animal basis
+ var/nutrition_step = 0.2 //nutrition lost per tick and per step, calculated from mob_size, 0.2 is a fallback
+ var/bite_factor = 0.4
+ var/digest_factor = 0.2 //A multiplier on how quickly reagents are digested
+ var/stomach_size_mult = 5
+
+ //Food behaviour vars
+ var/autoseek_food = 1//If 0. this animal will not automatically eat
+ var/beg_for_food = 1//If 0, this animal will not show interest in food held by a person
+ var/min_scan_interval = 1//Minimum and maximum number of procs between a foodscan. Animals will slow down if there's no food around for a while
+ var/max_scan_interval = 15
+ var/scan_interval = 5//current scan interval, clamped between min and max
+ //It gradually increases up to max when its left alone, to save performance
+ //It will drop back to 1 if it spies any food.
+ //This short time makes animals more responsive to interactions and more fun to play with
+
+ var/seek_speed = 2//How many tiles per second the animal will move towards food
+ var/seek_move_delay
+ var/scan_range = 6//How far around the animal will look for food
+ var/foodtarget = 0
+ //Used to control how often ian scans for nearby food
+
+
+
+/mob/living/simple_animal/proc/beg(var/atom/thing, var/atom/holder)
+ visible_emote("gazes longingly at [holder]'s [thing]")
+
/mob/living/simple_animal/New()
..()
+ seek_move_delay = (1 / seek_speed) / (world.tick_lag / 10)//number of ticks between moves
+ turns_since_scan = rand(min_scan_interval, max_scan_interval)//Randomise this at the start so animals don't sync up
+ health = maxHealth
verbs -= /mob/verb/observe
+ health = maxHealth
+ if (mob_size)
+ nutrition_step = mob_size * 0.03 * metabolic_factor
+ bite_factor = mob_size * 0.3
+ max_nutrition *= 1 + (nutrition_step*4)//Max nutrition scales faster than costs, so bigger creatures eat less often
+ reagents = new/datum/reagents(stomach_size_mult*mob_size, src)
+ else
+ reagents = new/datum/reagents(20, src)
+ nutrition = max_nutrition
+
+/mob/living/simple_animal/Move(NewLoc, direct)
+ . = ..()
+ if(.)
+ if(src.nutrition && src.stat != DEAD && hunger_enabled)
+ src.nutrition -= nutrition_step
+
+/mob/living/simple_animal/Released()
+ //These will cause mobs to immediately do things when released.
+ scan_interval = min_scan_interval
+ turns_since_move = turns_per_move
+ ..()
/mob/living/simple_animal/Login()
if(src && src.client)
src.client.screen = null
..()
-/mob/living/simple_animal/updatehealth()
- return
+/mob/living/simple_animal/examine(mob/user)
+ ..()
+
+ if (hunger_enabled)
+ if (!nutrition)
+ user << "It looks starving!"
+ else if (nutrition < max_nutrition *0.5)
+ user << "It looks hungry."
+ else if ((reagents.total_volume > 0 && nutrition > max_nutrition *0.75) || nutrition > max_nutrition *0.9)
+ user << "It looks full and contented."
/mob/living/simple_animal/Life()
..()
-
+ life_tick++
//Health
+ updatehealth()
+
if(stat == DEAD)
- if(health > 0)
- icon_state = icon_living
- dead_mob_list -= src
- living_mob_list += src
- stat = CONSCIOUS
- density = 1
return 0
-
- if(health <= 0)
- death()
- return
-
if(health > maxHealth)
health = maxHealth
handle_stunned()
handle_weakened()
handle_paralysed()
+ update_canmove()
handle_supernatural()
+ process_food()
+ handle_foodscanning()
//Movement
+ turns_since_move++
if(!client && !stop_automated_movement && wander && !anchored)
if(isturf(src.loc) && !resting && !buckled && canmove) //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)
if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled
- var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
+ /var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
moving_to = pick(cardinal)
dir = moving_to //How about we turn them the direction they are moving, yay.
Move(get_step(src,moving_to))
@@ -149,6 +209,7 @@
visible_emote("[pick(emote_see)].")
else
audible_emote("[pick(emote_hear)].")
+ speak_audio()
//Atmos
@@ -194,21 +255,56 @@
//Atmos effect
if(bodytemperature < minbodytemp)
fire_alert = 2
- adjustBruteLoss(cold_damage_per_tick)
+ apply_damage(cold_damage_per_tick, BURN, used_weapon = "Cold Temperature")
else if(bodytemperature > maxbodytemp)
fire_alert = 1
- adjustBruteLoss(heat_damage_per_tick)
+ apply_damage(heat_damage_per_tick, BURN, used_weapon = "High Temperature")
else
fire_alert = 0
if(!atmos_suitable)
- adjustBruteLoss(unsuitable_atoms_damage)
+ apply_damage(unsuitable_atoms_damage, OXY, used_weapon = "Atmosphere")
return 1
/mob/living/simple_animal/proc/handle_supernatural()
if(purge)
purge -= 1
+
+
+//Simple reagent processing for simple animals
+//This allows animals to digest food, and only food
+//Most drugs, poisons etc, are designed to work on carbons and affect many values a simple animal doesnt have
+/mob/living/simple_animal/proc/process_food()
+ if (hunger_enabled)
+ if (nutrition)
+ nutrition -= nutrition_step//Bigger animals get hungry faster
+ nutrition = max(0,min(nutrition, max_nutrition))//clamp the value
+ else
+ if (prob(3))
+ src << "You feel hungry..."
+
+
+ if (!reagents || !reagents.total_volume)
+ return
+
+ for(var/datum/reagent/current in reagents.reagent_list)
+ var/removed = min(current.metabolism*digest_factor, current.volume)
+ if (istype(current, /datum/reagent/nutriment))//If its food, it feeds us
+ var/datum/reagent/nutriment/N = current
+ nutrition += removed*N.nutriment_factor
+ health = min(health+(removed*N.regen_factor), maxHealth)
+ current.remove_self(removed)//If its not food, it just does nothing. no fancy effects
+
+/mob/living/simple_animal/can_eat()
+ if (!hunger_enabled || nutrition > max_nutrition * 0.9)
+ return 0//full
+
+ else if ((nutrition > max_nutrition * 0.8) || health < maxHealth)
+ return 1//content
+
+ else return 2//hungry
+
/mob/living/simple_animal/gib()
..(icon_gib,1)
@@ -216,18 +312,24 @@
if(act)
..(act, type, desc)
+//This is called when an animal 'speaks'. It does nothing here, but descendants should override it to add audio
+/mob/living/simple_animal/proc/speak_audio()
+ return
+
/mob/living/simple_animal/proc/visible_emote(var/act_desc)
custom_emote(1, act_desc)
/mob/living/simple_animal/proc/audible_emote(var/act_desc)
custom_emote(2, act_desc)
-/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
+/*
+mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj || Proj.nodamage)
return
adjustBruteLoss(Proj.damage)
return 0
+*/
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob)
..()
@@ -249,6 +351,9 @@
if (!(status_flags & CANPUSH))
return
+ if (!attempt_grab(M))
+ return
+
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
M.put_in_active_hand(G)
@@ -261,7 +366,7 @@
M.do_attack_animation(src)
if(I_HURT)
- adjustBruteLoss(harm_intent_damage)
+ apply_damage(harm_intent_damage, BRUTE, used_weapon = "Attack by [M.name]")
M.visible_message("\red [M] [response_harm] \the [src]")
M.do_attack_animation(src)
@@ -269,6 +374,7 @@
/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user)
if(istype(O, /obj/item/stack/medical))
+ user.changeNext_move(4)
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
@@ -282,32 +388,36 @@
M.show_message("[user] applies the [MED] on [src].")
else
user << "\The [src] is dead, medical items won't bring \him back to life."
- if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
+ else if(istype(O, /obj/item/weapon/reagent_containers))
+ ..()
+
+ else if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/material/knife) || istype(O, /obj/item/weapon/material/knife/butch))
harvest(user)
else
- if(!O.force)
- visible_message("[user] gently taps [src] with \the [O].")
- else
- O.attack(src, user, user.zone_sel.selecting)
+ attacked_with_item(O, user)
-/mob/living/simple_animal/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
+//TODO: refactor mob attackby(), attacked_by(), and friends.
+/mob/living/simple_animal/proc/attacked_with_item(var/obj/item/O, var/mob/user)
+ user.changeNext_move(8)
+ if(!O.force)
+ visible_message("[user] gently taps [src] with \the [O].")
+ return
- visible_message("\The [src] has been attacked with \the [O] by [user].")
+ if(O.force > resistance)
+ var/damage = O.force
+ if (O.damtype == HALLOSS)
+ damage = 0
+ if(supernatural && istype(O,/obj/item/weapon/nullrod))
+ damage *= 2
+ purge = 3
- if(O.force <= resistance)
- user << "This weapon is ineffective, it does no damage."
- return 2
+ apply_damage(damage, O.damtype, used_weapon = "[O.name]")
+ else
+ usr << "\The [src] has been attacked with the [O] by [user].")
+ user.do_attack_animation(src)
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later
@@ -318,6 +428,9 @@
tally = 1
tally *= purge
+ if (!nutrition)
+ tally += 4
+
return tally+config.animal_delay
/mob/living/simple_animal/Stat()
@@ -326,7 +439,14 @@
if(statpanel("Status") && show_stat_health)
stat(null, "Health: [round((health / maxHealth) * 100)]%")
+/mob/living/simple_animal/updatehealth()
+ ..()
+ if (health <= 0)
+ death()
+
/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
+ walk_to(src,0)
+ movement_target = null
icon_state = icon_dead
density = 0
return ..(gibbed,deathmessage)
@@ -336,19 +456,16 @@
flick("flash", flash)
switch (severity)
if (1.0)
- adjustBruteLoss(500)
+ apply_damage(500, BRUTE)
gib()
return
if (2.0)
- adjustBruteLoss(60)
+ apply_damage(60, BRUTE)
if(3.0)
- adjustBruteLoss(30)
-
-/mob/living/simple_animal/adjustBruteLoss(damage)
- health = Clamp(health - damage, 0, maxHealth)
+ apply_damage(30, BRUTE)
/mob/living/simple_animal/proc/SA_attackable(target_mob)
if (isliving(target_mob))
@@ -396,6 +513,82 @@
user.visible_message("[user] butchers \the [src] messily!")
gib()
+
+//Code to handle finding and nomming nearby food items
+/mob/living/simple_animal/proc/handle_foodscanning()
+ if (client || !hunger_enabled || !autoseek_food)
+ return 0
+
+ //Feeding, chasing food, FOOOOODDDD
+ if(!stat && !resting && !buckled)
+
+ turns_since_scan++
+ if(turns_since_scan >= scan_interval)
+ turns_since_scan = 0
+ if((movement_target) && (!(isturf(movement_target.loc) || ishuman(movement_target.loc))) || (foodtarget && !can_eat() ))
+ movement_target = null
+ foodtarget = 0
+ stop_automated_movement = 0
+ if( !movement_target || !(movement_target.loc in oview(src, 7)) )
+ walk_to(src,0)
+ movement_target = null
+ foodtarget = 0
+ stop_automated_movement = 0
+ if (can_eat())
+ for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,7))
+ if(isturf(S.loc) || ishuman(S.loc))
+ movement_target = S
+ foodtarget = 1
+ break
+
+ //Look for food in people's hand
+ if (!movement_target && beg_for_food)
+ var/obj/item/weapon/reagent_containers/food/snacks/F = null
+ for(var/mob/living/carbon/human/H in oview(src,scan_range))
+ if(istype(H.l_hand, /obj/item/weapon/reagent_containers/food/snacks))
+ F = H.l_hand
+
+ if(istype(H.r_hand, /obj/item/weapon/reagent_containers/food/snacks))
+ F = H.r_hand
+
+ if (F)
+ movement_target = F
+ foodtarget = 1
+ break
+
+ if(movement_target)
+ scan_interval = min_scan_interval
+ stop_automated_movement = 1
+
+ if (istype(movement_target.loc, /turf))
+ walk_to(src,movement_target,0, seek_move_delay)//Stand ontop of food
+ else
+ walk_to(src,movement_target.loc,1, seek_move_delay)//Don't stand ontop of people
+
+
+
+ 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) && Adjacent(get_turf(movement_target), src))
+ UnarmedAttack(movement_target)
+ if (get_turf(movement_target) == src.loc)
+ set_dir(pick(1,2,4,8,1,1))//Face a random direction when eating, but mostly upwards
+ else if(ishuman(movement_target.loc) && Adjacent(src, get_turf(movement_target)) && prob(15))
+ beg(movement_target, movement_target.loc)
+ else
+ scan_interval = max(min_scan_interval, min(scan_interval+1, max_scan_interval))//If nothing is happening, ian's scanning frequency slows down to save processing
+
+
//For picking up small animals
/mob/living/simple_animal/MouseDrop(atom/over_object)
if (holder_type)//we need a defined holder type in order for picking up to work
@@ -403,13 +596,13 @@
if(!istype(H) || !Adjacent(H))
return ..()
- get_scooped(H)
+ get_scooped(H, usr)
return
return ..()
+
/mob/living/simple_animal/handle_fire()
return
-
/mob/living/simple_animal/update_fire()
return
/mob/living/simple_animal/IgniteMob()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 198c3716e5c..38423925bfa 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -141,20 +141,20 @@
// Use for objects performing visible actions
// message is output to anyone who can see, e.g. "The [src] does something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
-/atom/proc/visible_message(var/message, var/blind_message)
- var/list/messageturfs = list()//List of turfs we broadcast to.
- var/list/messagemobs = list()//List of living mobs nearby who can hear it, and distant ghosts who've chosen to hear it
- for (var/turf in view(world.view, get_turf(src)))
- messageturfs += turf
-
- for(var/mob/M in player_list)
- if (!M.client || istype(M, /mob/new_player))
- continue
- if(get_turf(M) in messageturfs)
- messagemobs += M
-
- for(var/mob/M in messagemobs)
- M.show_message( message, 1, blind_message, 2)
+// /atom/proc/visible_message(var/message, var/blind_message)
+// var/list/messageturfs = list()//List of turfs we broadcast to.
+// var/list/messagemobs = list()//List of living mobs nearby who can hear it, and distant ghosts who've chosen to hear it
+// for (var/turf in view(world.view, get_turf(src)))
+// messageturfs += turf
+//
+// for(var/mob/M in player_list)
+// if (!M.client || istype(M, /mob/new_player))
+// continue
+// if(get_turf(M) in messageturfs)
+// messagemobs += M
+//
+// for(var/mob/M in messagemobs)
+// M.show_message( message, 1, blind_message, 2)
// Returns an amount of power drawn from the object (-1 if it's not viable).
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index 92c29d1dcbe..c30119c0e18 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -16,6 +16,8 @@
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill", fire_sound='sound/weapons/Laser.ogg'),
)
+ var/crit_fail = 0 //Added crit_fail as a local variable
+
/obj/item/weapon/gun/energy/gun/mounted
name = "mounted energy gun"
self_recharge = 1
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 6a2738a1d00..9b50b158686 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -150,7 +150,7 @@
M << "[src]'s reactor overloads!"
M << "You feel a wave of heat wash over you."
M.apply_effect(300, IRRADIATE)
- crit_fail = 1 //break the gun so it stops recharging
+ //crit_fail = 1 //break the gun so it stops recharging
processing_objects.Remove(src)
update_icon()
return 0
@@ -397,4 +397,3 @@ obj/item/weapon/gun/energy/staff/focus/attack_self(mob/living/user as mob)
charge_cost = 200
user << "The [src.name] will now strike only a single person."
projectile_type = /obj/item/projectile/forcebolt
-
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 447e1ebf257..1164b625c58 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -102,14 +102,14 @@
user << "\The [src] is empty."
return 1
- var/types = target.find_type()
+ //var/types = target.find_type()
var/mob/living/carbon/human/H
if(istype(target, /mob/living/carbon/human))
H = target
if(target == user)
if(istype(user, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
+ H = user
if(!H.check_has_mouth())
user << "Where do you intend to put \the [src]? You don't have a mouth!"
return 1
@@ -125,7 +125,7 @@
return 1
else
if(istype(target, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = target
+ H = target
if(!H.check_has_mouth())
user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!"
return
diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm
index ed1e30eadd9..1a3ef67b9b1 100644
--- a/code/modules/research/mechfab_designs.dm
+++ b/code/modules/research/mechfab_designs.dm
@@ -368,13 +368,15 @@
materials = list(DEFAULT_WALL_MATERIAL = 10000, "phoron" = 15000, "uranium" = 20000)
build_path = /obj/item/robot_parts/robot_component/jetpack
+/*
+//Commented out by nanako
/datum/design/item/robot_upgrade/rcd
name = "RCD module"
desc = "A rapid construction device module for use during construction operations."
id = "borg_rcd_module"
materials = list(DEFAULT_WALL_MATERIAL = 25000, "phoron" = 15000, "uranium" = 20000)
build_path = /obj/item/borg/upgrade/rcd
-
+*/
/datum/design/item/robot_upgrade/syndicate
name = "Illegal upgrade"
desc = "Allows for the construction of lethal upgrades for cyborgs."