Merge branch 'master' of https://github.com/PolarisSS13/Polaris into bone_fixer

# Conflicts:
#	icons/obj/abductor.dmi
This commit is contained in:
Anewbe
2017-09-25 20:35:19 -05:00
108 changed files with 1024 additions and 1402 deletions
+30 -1
View File
@@ -221,6 +221,7 @@
"Never Talk To Strangers",
"Sacrificial Victim",
"Unwitting Accomplice",
"Witting Accomplice",
"Bad For Business",
"Just Testing",
"Size Isn't Everything",
@@ -256,7 +257,35 @@
"Callsign",
"Three Ships in a Trenchcoat",
"Not Wearing Pants",
"Ridiculous Naming Convention"
"Ridiculous Naming Convention",
"God Dammit Morpheus",
"It Seemed Like a Good Idea",
"Legs All the Way Up",
"Purchase Necessary",
"Some Assembly Required",
"Buy One Get None Free",
"BRB",
"SHIP NAME HERE",
"Questionable Ethics",
"Accept Most Substitutes",
"I Blame the Government",
"Garbled Gibberish",
"Thinking Emoji",
"Is This Thing On?",
"Make My Day",
"No Vox Here",
"Savings and Values",
"Secret Name",
"Can't Find My Keys",
"Look Over There!",
"Made You Look!",
"Take Nothing Seriously",
"It Comes In Lime, Too",
"Loot Me",
"Nothing To Declare",
"Sneaking Suspicion",
"Bass Ackwards",
"Good Things Come to Those Who Freight"
)
+5 -5
View File
@@ -67,8 +67,8 @@
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
/obj/item/clothing/head/beret/sec/navy/hos
name = "officer beret"
desc = "A navy blue beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
name = "Head of Security beret"
desc = "A navy blue beret with a Head of Security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_navy_hos"
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
@@ -85,8 +85,8 @@
item_state_slots = list(slot_r_hand_str = "beret_black", slot_l_hand_str = "beret_black")
/obj/item/clothing/head/beret/sec/corporate/hos
name = "officer beret"
desc = "A corporate black beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
name = "Head of Security beret"
desc = "A corporate black beret with a Head of Security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_corporate_hos"
item_state_slots = list(slot_r_hand_str = "beret_black", slot_l_hand_str = "beret_black")
@@ -188,4 +188,4 @@
/obj/item/clothing/head/surgery/navyblue
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is navy blue."
icon_state = "surgcap_navyblue"
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
@@ -1,6 +1,6 @@
/obj/machinery/atmospherics/pipe
description_info = "This pipe, and all other pipes, can be connected or disconnected by a wrench. The internal pressure of the pipe must \
be below 300 kPa to do this. More pipes can be obtained from the pipe dispenser."
be less than 200 kPa above the ambient pressure to do this. More pipes can be obtained from the pipe dispenser."
/obj/machinery/atmospherics/pipe/New() //This is needed or else 20+ lines of copypasta to dance around inheritence.
..()
@@ -150,4 +150,4 @@
flags = OPENCONTAINER | NOREACT
complexity = 8
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
+1 -1
View File
@@ -125,7 +125,7 @@
if (force)
total_lighting_overlays--
global.lighting_update_overlays -= src
global.lighting_update_overlays_old -= src
LAZYREMOVE(SSlighting.currentrun, src)
var/turf/T = loc
if(istype(T))
+10 -2
View File
@@ -1,6 +1,14 @@
// Create lighting overlays on all turfs with dynamic lighting in areas with dynamic lighting.
/proc/create_all_lighting_overlays()
for(var/zlevel = 1 to world.maxz)
create_lighting_overlays_zlevel(zlevel)
for(var/area/A in world)
if(!A.dynamic_lighting)
continue
for(var/turf/T in A)
if(!T.dynamic_lighting)
continue
new /atom/movable/lighting_overlay(T, TRUE)
CHECK_TICK
CHECK_TICK
/proc/create_lighting_overlays_zlevel(var/zlevel)
ASSERT(zlevel)
+29 -37
View File
@@ -16,6 +16,30 @@
var/mob/living/carbon/brain/brainmob = null//The current occupant.
var/obj/item/organ/internal/brain/brainobj = null //The current brain organ.
var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/obj/item/device/radio/headset/mmi_radio/radio = null//Let's give it a radio.
/obj/item/device/mmi/New()
radio = new(src)//Spawns a radio inside the MMI.
/obj/item/device/mmi/verb/toggle_radio()
set name = "Toggle Brain Radio"
set desc = "Enables or disables the integrated brain radio, which is only usable outside of a body."
set category = "Object"
set src in usr
set popup_menu = 1
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if (radio.radio_enabled == 1)
radio.radio_enabled = 0
to_chat (usr, "You have disabled the [src]'s radio.")
to_chat (brainmob, "Your radio has been disabled.")
else if (radio.radio_enabled == 0)
radio.radio_enabled = 1
to_chat (usr, "You have enabled the [src]'s radio.")
to_chat (brainmob, "Your radio has been enabled.")
else
to_chat (usr, "You were unable to toggle the [src]'s radio.")
/obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO
@@ -110,48 +134,15 @@
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
borg.mmi = null
qdel_null(radio)
qdel_null(brainmob)
return ..()
/obj/item/device/mmi/radio_enabled
name = "radio-enabled man-machine interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio. Wait, don't they all?"
origin_tech = list(TECH_BIO = 4)
var/obj/item/device/radio/radio = null//Let's give it a radio.
New()
..()
radio = new(src)//Spawns a radio inside the MMI.
radio.broadcasting = 1//So it's broadcasting from the start.
verb//Allows the brain to toggle the radio functions.
Toggle_Broadcasting()
set name = "Toggle Broadcasting"
set desc = "Toggle broadcasting channel on or off."
set category = "MMI"
set src = usr.loc//In user location, or in MMI in this case.
set popup_menu = 0//Will not appear when right clicking.
if(brainmob.stat)//Only the brainmob will trigger these so no further check is necessary.
brainmob << "Can't do that while incapacitated or dead."
radio.broadcasting = radio.broadcasting==1 ? 0 : 1
brainmob << "<span class='notice'>Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting.</span>"
Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
if(brainmob.stat)
brainmob << "Can't do that while incapacitated or dead."
radio.listening = radio.listening==1 ? 0 : 1
brainmob << "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>"
/obj/item/device/mmi/emp_act(severity)
if(!brainmob)
return
@@ -177,13 +168,14 @@
/obj/item/device/mmi/digital/New()
src.brainmob = new(src)
src.brainmob.add_language("Robot Talk")
// src.brainmob.add_language("Robot Talk")//No binary without a binary communication device
src.brainmob.add_language(LANGUAGE_GALCOM)
src.brainmob.add_language(LANGUAGE_EAL)
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.stat = 0
src.brainmob.silent = 0
radio = new(src)
dead_mob_list -= src.brainmob
/obj/item/device/mmi/digital/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -271,7 +263,7 @@
src.brainmob << "<b>You are a [src], brought into existence on [station_name()].</b>"
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
src.brainmob << "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
src.brainmob << "<b>Use say #b to speak to other artificial intelligences.</b>"
// src.brainmob << "<b>Use say #b to speak to other artificial intelligences.</b>"
src.brainmob.mind.assigned_role = "Synthetic Brain"
var/turf/T = get_turf_or_move(src.loc)
@@ -60,5 +60,5 @@
/mob/living/carbon/brain/isSynthetic()
return istype(loc, /obj/item/device/mmi)
/mob/living/carbon/brain/binarycheck()
return isSynthetic()
///mob/living/carbon/brain/binarycheck()//No binary without a binary communication device
// return isSynthetic()
+13 -5
View File
@@ -22,7 +22,7 @@
verb="asks"
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
if(prob(10))//10% chance to drop the message entirely
return
else
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
@@ -31,8 +31,16 @@
speaking.broadcast(src,trim(message))
return
if(istype(container, /obj/item/device/mmi/radio_enabled))
var/obj/item/device/mmi/radio_enabled/R = container
if(R.radio)
spawn(0) R.radio.hear_talk(src, sanitize(message), verb, speaking)
..(trim(message), speaking, verb)
/mob/living/carbon/brain/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode)
var/obj/item/device/mmi/R = container
if (R.radio && R.radio.radio_enabled)
if(message_mode == "general")
message_mode = null
return R.radio.talk_into(src,message,message_mode,verb,speaking)
else
src << "<span class='danger'>Your radio is disabled.</span>"
return 0
+5 -5
View File
@@ -220,15 +220,15 @@
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames!</span>",
"<span class='warning'>You try to pat out [src]'s flames! Hot!</span>")
if(do_mob(M, src, 15))
src.fire_stacks -= 0.5
src.adjust_fire_stacks(-0.5)
if (prob(10) && (M.fire_stacks <= 0))
M.fire_stacks += 1
M.adjust_fire_stacks(1)
M.IgniteMob()
if (M.on_fire)
M.visible_message("<span class='danger'>The fire spreads from [src] to [M]!</span>",
"<span class='danger'>The fire spreads to you as well!</span>")
else
src.fire_stacks -= 0.5 //Less effective than stop, drop, and roll - also accounting for the fact that it takes half as long.
src.adjust_fire_stacks(-0.5) //Less effective than stop, drop, and roll - also accounting for the fact that it takes half as long.
if (src.fire_stacks <= 0)
M.visible_message("<span class='warning'>[M] successfully pats out [src]'s flames.</span>",
"<span class='warning'>You successfully pat out [src]'s flames.</span>")
@@ -264,8 +264,8 @@
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
if(M.fire_stacks >= (src.fire_stacks + 3))
src.fire_stacks += 1
M.fire_stacks -= 1
src.adjust_fire_stacks(1)
M.adjust_fire_stacks(-1)
if(M.on_fire)
src.IgniteMob()
AdjustParalysis(-3)
@@ -10,7 +10,7 @@
delete_inventory()
/mob/living/carbon/human/skrell/New(var/new_loc)
h_style = "Skrell Male Tentacles"
h_style = "Skrell Short Tentacles"
..(new_loc, "Skrell")
/mob/living/carbon/human/tajaran/New(var/new_loc)
+19 -14
View File
@@ -2,7 +2,7 @@
//drop && roll
if(on_fire && !buckled)
fire_stacks -= 1.2
adjust_fire_stacks(-1.2)
Weaken(3)
spin(32,2)
visible_message(
@@ -66,38 +66,43 @@
drop_from_inventory(handcuffed)
/mob/living/carbon/proc/escape_legcuffs()
if(!canClick())
return
//if(!(last_special <= world.time)) return
//This line represent a significant buff to grabs...
// We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_legcuffs()
return
var/obj/item/weapon/legcuffs/HC = legcuffed
var/obj/item/weapon/handcuffs/legcuffs/LC = legcuffed
//A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
//A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/handcuffs/legcuffs type
var/breakouttime = 1200
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
//If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
if(istype(HC))
breakouttime = HC.breakouttime
//If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
if(istype(LC))
breakouttime = LC.breakouttime
displaytime = breakouttime / 600 //Minutes
var/mob/living/carbon/human/H = src
if(istype(H) && H.shoes && istype(H.shoes,/obj/item/clothing/shoes/magboots/rig))
breakouttime /= 2
displaytime /= 2
visible_message(
"<span class='danger'>[usr] attempts to remove \the [HC]!</span>",
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
"<span class='danger'>\The [src] attempts to remove \the [LC]!</span>",
"<span class='warning'>You attempt to remove \the [LC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!legcuffed || buckled)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
if(!legcuffed)
return
visible_message(
"<span class='danger'>[src] manages to remove \the [legcuffed]!</span>",
"<span class='danger'>\The [src] manages to remove \the [legcuffed]!</span>",
"<span class='notice'>You successfully remove \the [legcuffed].</span>"
)
drop_from_inventory(legcuffed)
legcuffed = null
update_inv_legcuffed()
@@ -1,6 +1,11 @@
// Hivebots are tuned towards how many default lasers are needed to kill them.
// As such, if laser damage is ever changed, you should change this define.
#define LASERS_TO_KILL *40
// Default hivebot is melee, and a bit more meaty, so it can meatshield for their ranged friends.
/mob/living/simple_animal/hostile/hivebot
name = "Hivebot"
desc = "A small robot"
name = "hivebot"
desc = "A robot. It appears to be somewhat reslient, but lacking a true weapon."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
@@ -8,16 +13,16 @@
faction = "hivebot"
intelligence_level = SA_ROBOTIC
maxHealth = 15
health = 15
maxHealth = 3 LASERS_TO_KILL
health = 3 LASERS_TO_KILL
speed = 4
melee_damage_lower = 2
melee_damage_upper = 3
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "clawed"
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
projectiletype = /obj/item/projectile/bullet/hivebot
min_oxy = 0
max_oxy = 0
@@ -29,19 +34,102 @@
max_n2 = 0
minbodytemp = 0
cooperative = TRUE
firing_lines = TRUE
investigates = TRUE
speak_chance = 1
speak = list(
"Resuming task: Protect area.",
"No threats found.",
"Error: No targets found."
)
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("Affirmative.", "Positive")
say_cannot = list("Denied.", "Negative")
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
// Subtypes.
// Melee like the base type, but more fragile.
/mob/living/simple_animal/hostile/hivebot/swarm
name = "swarm hivebot"
desc = "A robot. It looks fragile and weak"
maxHealth = 1 LASERS_TO_KILL
health = 1 LASERS_TO_KILL
melee_damage_lower = 3
melee_damage_upper = 3
// This one has a semi-weak ranged attack.
/mob/living/simple_animal/hostile/hivebot/range
name = "Hivebot"
desc = "A smallish robot, this one is armed!"
name = "ranged hivebot"
desc = "A robot. It has a simple ballistic weapon."
ranged = 1
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// This one shoots a burst of three, and is considerably more dangerous.
/mob/living/simple_animal/hostile/hivebot/range/rapid
name = "rapid hivebot"
desc = "A robot. It has a fast firing ballistic rifle."
icon_living = "strong"
rapid = 1
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
/mob/living/simple_animal/hostile/hivebot/strong
name = "Strong Hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
ranged = 1
// Shoots EMPs, to screw over other robots.
/mob/living/simple_animal/hostile/hivebot/range/ion
name = "engineering hivebot"
desc = "A robot. It has a tool which emits focused electromagnetic pulses, which are deadly to other synthetic adverseries."
projectiletype = /obj/item/projectile/ion
projectilesound = 'sound/weapons/Laser.ogg'
icon_living = "engi"
ranged = TRUE
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// Shoots deadly lasers.
/mob/living/simple_animal/hostile/hivebot/range/laser
name = "laser hivebot"
desc = "A robot. It has an energy weapon."
projectiletype = /obj/item/projectile/beam/blue
projectilesound = 'sound/weapons/Laser.ogg'
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// Beefy and ranged.
/mob/living/simple_animal/hostile/hivebot/range/strong
name = "strong hivebot"
desc = "A robot. This one has reinforced plating, and looks tougher."
icon_living = "strong"
maxHealth = 4 LASERS_TO_KILL
health = 4 LASERS_TO_KILL
melee_damage_lower = 15
melee_damage_upper = 15
// Also beefy, but tries to stay at their 'home', ideal for base defense.
/mob/living/simple_animal/hostile/hivebot/range/guard
name = "guard hivebot"
desc = "A robot. It seems to be guarding something."
returns_home = TRUE
maxHealth = 4 LASERS_TO_KILL
health = 4 LASERS_TO_KILL
// This one is intended for players to use. Well rounded and can make other hivebots follow them with verbs.
/mob/living/simple_animal/hostile/hivebot/range/player
name = "commander hivebot"
desc = "A robot. This one seems to direct the others, and it has a laser weapon."
icon_living = "commander"
maxHealth = 5 LASERS_TO_KILL
health = 5 LASERS_TO_KILL
projectiletype = /obj/item/projectile/beam/blue
projectilesound = 'sound/weapons/Laser.ogg'
melee_damage_lower = 15 // Needed to force open airlocks.
melee_damage_upper = 15
// Procs.
/mob/living/simple_animal/hostile/hivebot/death()
..()
@@ -52,6 +140,42 @@
s.start()
qdel(src)
/mob/living/simple_animal/hostile/hivebot/speech_bubble_appearance()
return "synthetic_evil"
/mob/living/simple_animal/hostile/hivebot/verb/command_follow()
set name = "Command - Follow"
set category = "Hivebot"
set desc = "This will ask other hivebots to follow you."
say("Delegating new task: Follow.")
for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
if(buddy.faction != faction)
continue
if(buddy == src)
continue
buddy.set_follow(src)
buddy.FollowTarget()
spawn(rand(5, 10))
buddy.say( pick(buddy.say_understood) )
/mob/living/simple_animal/hostile/hivebot/verb/command_stop()
set name = "Command - Stop Following"
set category = "Hivebot"
set desc = "This will ask other hivebots to cease following you."
say("Delegating new task: Stop following.")
for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
if(buddy.faction != faction)
continue
if(buddy == src)
continue
buddy.LoseFollow()
spawn(rand(5, 10))
buddy.say( pick(buddy.say_understood) )
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
name = "Beacon"
desc = "Some odd beacon thing"
@@ -107,6 +231,6 @@
if(prob(2))//Might be a bit low, will mess with it likely
warpbots()
/obj/item/projectile/hivebotbullet
/obj/item/projectile/bullet/hivebot
damage = 10
damage_type = BRUTE
@@ -43,6 +43,17 @@
var/poison_per_bite = 5
var/poison_chance = 10
var/poison_type = "spidertoxin"
var/image/eye_layer = null
/mob/living/simple_animal/hostile/giant_spider/proc/add_eyes()
if(!eye_layer)
var/overlay_layer = LIGHTING_LAYER+0.1
eye_layer = image(icon, "[icon_state]-eyes", overlay_layer)
overlays += eye_layer
/mob/living/simple_animal/hostile/giant_spider/proc/remove_eyes()
overlays -= eye_layer
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
@@ -61,6 +72,7 @@
var/fed = 0
var/atom/cocoon_target
var/egg_inject_chance = 5
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
@@ -96,33 +108,43 @@
/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent)
get_light_and_color(parent)
add_eyes()
..()
/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/death()
remove_eyes()
..()
/mob/living/simple_animal/hostile/giant_spider/nurse/PunchTarget()
/mob/living/simple_animal/hostile/giant_spider/DoPunch(var/atom/A)
. = ..()
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 = new /obj/effect/spider/eggcluster/small(O, src)
O.implants += eggs
H << "<span class='warning'>The [src] injects something into your [O.name]!</span>"
if(.) // If we succeeded in hitting.
if(isliving(A))
var/mob/living/L = A
if(L.reagents)
var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
if(L.can_inject(src, null, target_zone))
L.reagents.add_reagent(poison_type, poison_per_bite)
if(prob(poison_chance))
to_chat(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/DoPunch(var/atom/A)
. = ..()
if(.) // If we succeeded in hitting.
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(prob(egg_inject_chance))
var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
if(H.can_inject(src, null, target_zone))
var/obj/item/organ/external/O = H.get_organ(target_zone)
var/eggcount
for(var/obj/I in O.implants)
if(istype(I, /obj/effect/spider/eggcluster))
eggcount ++
if(!eggcount)
var/eggs = new /obj/effect/spider/eggcluster/small(O, src)
O.implants += eggs
to_chat(H, "<font size='3'><span class='warning'>\The [src] injects something into your [O.name]!</span></font>")
/mob/living/simple_animal/hostile/giant_spider/handle_stance()
. = ..()
@@ -1230,14 +1230,22 @@
// This is the actual act of 'punching'. Override for special behaviour.
/mob/living/simple_animal/proc/DoPunch(var/atom/A)
if(!Adjacent(target_mob)) // They could've moved in the meantime.
return
return FALSE
var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.outgoing_melee_damage_percent))
damage_to_do *= M.outgoing_melee_damage_percent
// SA attacks can be blocked with shields.
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(damage = damage_to_do, damage_source = src, attacker = src, def_zone = null, attack_text = "the attack"))
return FALSE
A.attack_generic(src, damage_to_do, attacktext)
return TRUE
//The actual top-level ranged attack proc
/mob/living/simple_animal/proc/ShootTarget()
+4
View File
@@ -501,6 +501,10 @@
if(!dense_object && (locate(/obj/structure/lattice) in oview(1, src)))
dense_object++
if(!dense_object && (locate(/obj/structure/catwalk) in oview(1, src)))
dense_object++
//Lastly attempt to locate any dense objects we could push off of
//TODO: If we implement objects drifing in space this needs to really push them
//Due to a few issues only anchored and dense objects will now work.
@@ -1020,6 +1020,17 @@
icon_state = "teshari_mushroom"
species_allowed = list("Teshari")
// Vox things
vox_braid_long
name = "Long Vox braid"
icon_state = "vox_longbraid"
species_allowed = list("Vox")
vox_braid_short
name = "Short Vox Braid"
icon_state = "vox_shortbraid"
species_allowed = list("Vox")
vox_quills_short
name = "Short Vox Quills"
icon_state = "vox_shortquills"
+1 -1
View File
@@ -9,7 +9,7 @@ var/datum/planet/sif/planet_sif = null
breathable atmosphere, a magnetic field, weather, and similar gravity to Earth. It is currently the capital planet of Vir. \
Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki.
current_time = new /datum/time/sif() // 32 hour clocks are nice.
expected_z_levels = list(1) // To be changed when real map is finished.
// expected_z_levels = list(1) // To be changed when real map is finished.
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
/datum/planet/sif/New()
+58 -6
View File
@@ -565,15 +565,19 @@ obj/structure/cable/proc/cableColor(var/colorC)
w_class = ITEMSIZE_SMALL
/obj/item/stack/cable_coil/examine(mob/user)
if(get_dist(src, user) > 1)
return
var/msg = ""
if(get_amount() == 1)
to_chat(user, "A short piece of power cable.")
msg += "A short piece of power cable."
else if(get_amount() == 2)
to_chat(user, "A piece of power cable.")
msg += "A piece of power cable."
else
to_chat(user, "A coil of power cable. There are [get_amount()] lengths of cable in the coil.")
msg += "A coil of power cable."
if(get_dist(src, user) <= 1)
msg += " There are [get_amount()] lengths of cable in the coil."
to_chat(user, msg)
/obj/item/stack/cable_coil/verb/make_restraint()
@@ -875,4 +879,52 @@ obj/structure/cable/proc/cableColor(var/colorC)
/obj/item/stack/cable_coil/random/New()
stacktype = /obj/item/stack/cable_coil
color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN, COLOR_SILVER, COLOR_GRAY, COLOR_BLACK, COLOR_MAROON, COLOR_OLIVE, COLOR_LIME, COLOR_TEAL, COLOR_NAVY, COLOR_PURPLE, COLOR_BEIGE, COLOR_BROWN)
..()
..()
//Endless alien cable coil
/obj/item/stack/cable_coil/alien
name = "alien spool"
icon = 'icons/obj/abductor.dmi'
icon_state = "coil"
amount = MAXCOIL
max_amount = MAXCOIL
color = COLOR_SILVER
desc = "A spool of cable. No matter how hard you try, you can never seem to get to the end."
throwforce = 10
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20)
flags = CONDUCT
slot_flags = SLOT_BELT
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
stacktype = null
/obj/item/stack/cable_coil/alien/New(loc, length = MAXCOIL, var/param_color = null) //There has to be a better way to do this.
if(embed_chance == -1) //From /obj/item, don't want to do what the normal cable_coil does
if(sharp)
embed_chance = force/w_class
else
embed_chance = force/(w_class*3)
update_icon()
/obj/item/stack/cable_coil/alien/update_icon()
icon_state = initial(icon_state)
/obj/item/stack/cable_coil/alien/use() //It's endless
return
/obj/item/stack/cable_coil/alien/add() //Still endless
return
/obj/item/stack/cable_coil/alien/update_wclass()
return
/obj/item/stack/cable_coil/alien/examine(mob/user)
var/msg = "A spool of cable."
if(get_dist(src, user) <= 1)
msg += " It doesn't seem to have a beginning, or an end."
to_chat(user, msg)
+16 -8
View File
@@ -16,7 +16,7 @@
/obj/item/weapon/cell/process()
if(self_recharge)
give(charge_amount / CELLRATE)
give(charge_amount)
else
return PROCESS_KILL
@@ -59,6 +59,7 @@
return 0
var/used = min(charge, amount)
charge -= used
update_icon()
return used
// Checks if the specified amount can be provided. If it can, it removes the amount
@@ -78,24 +79,29 @@
if(maxcharge < amount) return 0
var/amount_used = min(maxcharge-charge,amount)
charge += amount_used
update_icon()
return amount_used
/obj/item/weapon/cell/examine(mob/user)
if(get_dist(src, user) > 1)
return
var/msg = desc
if(maxcharge <= 2500)
user << "[desc]\nThe manufacturer's label states this cell has a power rating of [maxcharge], and that you should not swallow it.\nThe charge meter reads [round(src.percent() )]%."
else
user << "This power cell has an exciting chrome finish, as it is an uber-capacity cell type! It has a power rating of [maxcharge]!\nThe charge meter reads [round(src.percent() )]%."
if(get_dist(src, user) <= 1)
msg += " It has a power rating of [maxcharge].\nThe charge meter reads [round(src.percent() )]%."
to_chat(user, msg)
/*
if(maxcharge <= 2500)
to_chat(user, "[desc]\nThe manufacturer's label states this cell has a power rating of [maxcharge], and that you should not swallow it.\nThe charge meter reads [round(src.percent() )]%.")
else
to_chat(user, "This power cell has an exciting chrome finish, as it is an uber-capacity cell type! It has a power rating of [maxcharge]!\nThe charge meter reads [round(src.percent() )]%.")
*/
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/weapon/reagent_containers/syringe))
var/obj/item/weapon/reagent_containers/syringe/S = W
user << "You inject the solution into the power cell."
to_chat(user, "You inject the solution into the power cell.")
if(S.reagents.has_reagent("phoron", 5))
@@ -149,6 +155,8 @@
charge -= charge / severity
if (charge < 0)
charge = 0
update_icon()
..()
/obj/item/weapon/cell/ex_act(severity)
@@ -264,15 +264,7 @@
if(eye_shield < 1)
l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) )
/*
//adjusted range so that a power of 170 (pretty high) results in 9 tiles, roughly the distance from the core to the engine monitoring room.
//note that the rads given at the maximum range is a constant 0.2 - as power increases the maximum range merely increases.
for(var/mob/living/l in range(src, round(sqrt(power / 2))))
var/radius = max(get_dist(l, src), 1)
var/rads = (power / 10) * ( 1 / (radius**2) )
l.apply_effect(rads, IRRADIATE)
*/
radiation_repository.radiate(src, power * 1.5) //Better close those shutters!
radiation_repository.radiate(src, max(power * 1.5, 50) ) //Better close those shutters!
power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation
@@ -335,16 +327,6 @@
ui.set_auto_update(1)
/*
/obj/machinery/power/supermatter/proc/transfer_energy()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
var/distance = get_dist(R, src)
if(distance <= 15)
//for collectors using standard phoron tanks at 1013 kPa, the actual power generated will be this power*POWER_FACTOR*20*29 = power*POWER_FACTOR*580
R.receive_pulse(power * POWER_FACTOR * (min(3/distance, 1))**2)
return
*/
/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
user.visible_message("<span class=\"warning\">\The [user] touches \a [W] to \the [src] as a silence fills the room...</span>",\
"<span class=\"danger\">You touch \the [W] to \the [src] when everything suddenly goes silent.\"</span>\n<span class=\"notice\">\The [W] flashes into dust as you flinch away from \the [src].</span>",\
+3 -2
View File
@@ -202,8 +202,9 @@
admin_attack_log(firer, target_mob, attacker_message, victim_message, admin_message)
else
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with <b>\a [src]</b>"
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with \a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target_mob.x];Y=[target_mob.y];Z=[target_mob.z]'>JMP</a>)")
if(target_mob) // Sometimes the target_mob gets gibbed or something.
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with <b>\a [src]</b>"
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with \a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target_mob.x];Y=[target_mob.y];Z=[target_mob.z]'>JMP</a>)")
//sometimes bullet_act() will want the projectile to continue flying
if (result == PROJECTILE_CONTINUE)
@@ -284,13 +284,21 @@
/datum/reagent/frostoil/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.bodytemperature = max(M.bodytemperature - 10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
M.bodytemperature = max(M.bodytemperature - 10 * TEMPERATURE_DAMAGE_COEFFICIENT, 215)
if(prob(1))
M.emote("shiver")
if(istype(M, /mob/living/simple_animal/slime))
M.bodytemperature = max(M.bodytemperature - rand(10,20), 0)
holder.remove_reagent("capsaicin", 5)
/datum/reagent/frostoil/cryotoxin //A longer lasting version of frost oil.
name = "Cryotoxin"
id = "cryotoxin"
description = "Lowers the body's internal temperature."
reagent_state = LIQUID
color = "#B31008"
metabolism = REM * 0.5
/datum/reagent/capsaicin
name = "Capsaicin Oil"
id = "capsaicin"
@@ -105,8 +105,8 @@
/datum/reagent/toxin/phoron/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_VOX)
M.adjustOxyLoss(-removed * 9)
return
M.adjustOxyLoss(-100 * removed) //5 oxyloss healed per tick.
return //You're wasting plasma (a semi-limited chemical) to save someone, so it might as well be somewhat strong.
..()
/datum/reagent/toxin/phoron/touch_turf(var/turf/simulated/T, var/amount)
@@ -146,3 +146,22 @@
underlays += I
else continue
side = "right"
/obj/item/weapon/reagent_containers/food/drinks/glass2/afterattack(var/obj/target, var/mob/user, var/proximity)
if(user.a_intent == I_HURT) //We only want splashing to be done if they are on harm intent.
if(!is_open_container() || !proximity)
return 1
if(standard_splash_mob(user, target))
return 1
if(reagents && reagents.total_volume) //They are on harm intent, aka wanting to spill it.
user << "<span class='notice'>You splash the solution onto [target].</span>"
reagents.splash(target, reagents.total_volume)
return 1
else
return
/obj/item/weapon/reagent_containers/food/drinks/glass2/standard_feed_mob(var/mob/user, var/mob/target)
if(afterattack()) //Check to see if harm intent & splash.
return
else
..() //If they're splashed, no need to do anything else.
@@ -78,25 +78,27 @@
/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/proximity)
if(!is_open_container() || !proximity)
return
if(!is_open_container() || !proximity) //Is the container open & are they next to whatever they're clicking?
return //If not, do nothing.
for(var/type in can_be_placed_into)
for(var/type in can_be_placed_into) //Is it something it can be placed into?
if(istype(target, type))
return
if(standard_splash_mob(user, target))
return
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
if(standard_dispenser_refill(user, target)) //Are they clicking a water tank/some dispenser?
return
if(reagents && reagents.total_volume)
user << "<span class='notice'>You splash the solution onto [target].</span>"
reagents.splash(target, reagents.total_volume)
if(standard_pour_into(user, target)) //Pouring into another beaker?
return
if(user.a_intent == I_HURT) //Harm intent?
if(standard_splash_mob(user, target)) //If harm intent and can splash a mob, go ahead.
return
if(reagents && reagents.total_volume) //Otherwise? Splash the floor.
user << "<span class='notice'>You splash the solution onto [target].</span>"
reagents.splash(target, reagents.total_volume)
return
/obj/item/weapon/reagent_containers/glass/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen))
var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN)
+12 -12
View File
@@ -648,14 +648,14 @@ other types of metals and chemistry for reagents).
/datum/design/item/weapon/slimebation
id = "slimebation"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3, TECH_COMBAT = 3)
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2, TECH_POWER = 3, TECH_COMBAT = 3)
materials = list(DEFAULT_WALL_MATERIAL = 5000)
build_path = /obj/item/weapon/melee/baton/slime
sort_string = "TBAAB"
/datum/design/item/weapon/slimetaser
id = "slimetaser"
req_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_POWER = 4, TECH_COMBAT = 4)
req_tech = list(TECH_MATERIAL = 3, TECH_BIO = 3, TECH_POWER = 4, TECH_COMBAT = 4)
materials = list(DEFAULT_WALL_MATERIAL = 5000)
build_path = /obj/item/weapon/gun/energy/taser/xeno
sort_string = "TBAAC"
@@ -744,6 +744,16 @@ other types of metals and chemistry for reagents).
build_path = /obj/item/device/aicard
sort_string = "VACAA"
/datum/design/item/dronebrain
name = "Robotic intelligence circuit"
id = "dronebrain"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_DATA = 4)
build_type = PROTOLATHE | PROSFAB
materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500)
build_path = /obj/item/device/mmi/digital/robot
category = "Misc"
sort_string = "VACAC"
/datum/design/item/posibrain
name = "Positronic brain"
id = "posibrain"
@@ -764,16 +774,6 @@ other types of metals and chemistry for reagents).
category = "Misc"
sort_string = "VACBA"
/datum/design/item/mmi_radio
name = "Radio-enabled man-machine interface"
id = "mmi_radio"
req_tech = list(TECH_DATA = 2, TECH_BIO = 4)
build_type = PROTOLATHE | PROSFAB
materials = list(DEFAULT_WALL_MATERIAL = 1200, "glass" = 500)
build_path = /obj/item/device/mmi/radio_enabled
category = "Misc"
sort_string = "VACBB"
/datum/design/item/beacon
name = "Bluespace tracking beacon design"
id = "beacon"
+6 -1
View File
@@ -139,6 +139,11 @@
var/check_delay = 60 //periodically recheck if we need to rebuild a shield
use_power = 0
idle_power_usage = 0
var/global/list/blockedturfs = list(
/turf/space,
/turf/simulated/open,
/turf/simulated/floor/outdoors,
)
/obj/machinery/shieldgen/Destroy()
collapse_shields()
@@ -169,7 +174,7 @@
/obj/machinery/shieldgen/proc/create_shields()
for(var/turf/target_tile in range(2, src))
if (istype(target_tile,/turf/space) && !(locate(/obj/machinery/shield) in target_tile))
if (is_type_in_list(target_tile,blockedturfs) && !(locate(/obj/machinery/shield) in target_tile))
if (malfunction && prob(33) || !malfunction)
var/obj/machinery/shield/S = new/obj/machinery/shield(target_tile)
deployed_shields += S
@@ -3,7 +3,11 @@
/obj/machinery/shield_gen/external
name = "hull shield generator"
var/global/list/blockedturfs = list(
/turf/space,
/turf/simulated/open,
/turf/simulated/floor/outdoors,
)
/obj/machinery/shield_gen/external/New()
..()
@@ -18,7 +22,7 @@
for (var/x_offset = -field_radius; x_offset <= field_radius; x_offset++)
for (var/y_offset = -field_radius; y_offset <= field_radius; y_offset++)
T = locate(gen_turf.x + x_offset, gen_turf.y + y_offset, gen_turf.z)
if (istype(T, /turf/space))
if (is_type_in_list(T,blockedturfs))
//check neighbors of T
if (locate(/turf/simulated/) in orange(1, T))
out += T
@@ -259,8 +259,7 @@
..()
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
if(istype(P,/obj/item/projectile/bullet) ||\
istype(P,/obj/item/projectile/hivebotbullet))
if(istype(P,/obj/item/projectile/bullet))
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
+1 -1
View File
@@ -6,7 +6,7 @@
slot_flags = SLOT_BELT
force = 9
lightcolor = "#33CCFF"
origin_tech = list(TECH_COMBAT = 2, TECH_BIO = 4)
origin_tech = list(TECH_COMBAT = 2, TECH_BIO = 2)
agonyforce = 10 //It's not supposed to be great at stunning human beings.
hitcost = 48 //Less zap for less cost
description_info = "This baton will stun a slime or other lesser lifeform for about five seconds, if hit with it while on."