Merge pull request #5954 from Zuhayr/dev

No one is going to read this all anyway
This commit is contained in:
Chinsky
2014-08-13 18:33:09 +04:00
67 changed files with 636 additions and 492 deletions

View File

@@ -120,7 +120,7 @@ var/global/floorIsLava = 0
body += "<A href='?src=\ref[src];makeanimal=\ref[M]'>Animalize</A> | "
// DNA2 - Admin Hax
if(iscarbon(M))
if(M.dna && iscarbon(M))
body += "<br><br>"
body += "<b>DNA Blocks:</b><br><table border='0'><tr><th>&nbsp;</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th>"
var/bname
@@ -369,21 +369,21 @@ var/global/floorIsLava = 0
if(6)
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed story to Network.</B></FONT><HR><BR>"
if(src.admincaster_feed_channel.channel_name=="")
dat+="<FONT COLOR='maroon'><EFBFBD>Invalid receiving channel name.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Invalid receiving channel name.</FONT><BR>"
if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'><EFBFBD>Invalid message body.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Invalid message body.</FONT><BR>"
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[3]'>Return</A><BR>"
if(7)
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed Channel to Network.</B></FONT><HR><BR>"
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'><EFBFBD>Invalid channel name.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Invalid channel name.</FONT><BR>"
var/check = 0
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
if(check)
dat+="<FONT COLOR='maroon'><EFBFBD>Channel name already in use.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Channel name already in use.</FONT><BR>"
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[2]'>Return</A><BR>"
if(9)
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.author]</FONT>\]</FONT><HR>"
@@ -497,9 +497,9 @@ var/global/floorIsLava = 0
if(16)
dat+="<B><FONT COLOR='maroon'>ERROR: Wanted Issue rejected by Network.</B></FONT><HR><BR>"
if(src.admincaster_feed_message.author =="" || src.admincaster_feed_message.author == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'><EFBFBD>Invalid name for person wanted.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Invalid name for person wanted.</FONT><BR>"
if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'><EFBFBD>Invalid description.</FONT><BR>"
dat+="<FONT COLOR='maroon'>•Invalid description.</FONT><BR>"
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
if(17)
dat+={"
@@ -1142,4 +1142,4 @@ var/global/floorIsLava = 0
//
//ALL DONE
//*********************************************************************************************************
//
//

View File

@@ -310,7 +310,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
else
if(alert("Spawn that person a tome?",,"Yes","No")=="Yes")
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground."
new /obj/item/weapon/tome(M.loc)
new /obj/item/weapon/book/tome(M.loc)
else
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
var/glimpse=pick("1","2","3","4","5","6","7","8")

View File

@@ -33,16 +33,21 @@
return 1
/obj/item/clothing/proc/refit_for_species(var/target_species)
//Set species_restricted list
switch(target_species)
if("Human", "Skrell") //humanoid bodytypes
species_restricted = list("exclude","Unathi","Tajaran","Diona","Vox")
else
species_restricted = list(target_species)
//Set icon
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
else
icon = initial(icon)
/obj/item/clothing/head/helmet/refit_for_species(var/target_species)
//Set species_restricted list
switch(target_species)
if("Skrell")
species_restricted = list("exclude","Unathi","Tajaran","Diona","Vox")
@@ -51,8 +56,11 @@
else
species_restricted = list(target_species)
//Set icon
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
else
icon = initial(icon)
//Ears: headsets, earmuffs and tiny objects

View File

@@ -20,6 +20,9 @@
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi'
)
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi',
)
attack_self(mob/user)
if(!isturf(user.loc))
@@ -65,6 +68,9 @@
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi'
)
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi',
)
//Breach thresholds, should ideally be inherited by most (if not all) hardsuits.
breach_threshold = 18
@@ -299,9 +305,6 @@
icon_state = "rig0-engineering"
item_state = "eng_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi',
)
/obj/item/clothing/suit/space/rig/engineering
name = "engineering hardsuit"
@@ -311,9 +314,6 @@
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi',
)
//Chief Engineer's rig
/obj/item/clothing/head/helmet/space/rig/engineering/chief
@@ -323,7 +323,6 @@
item_state = "ce_helm"
item_color = "white"
sprite_sheets = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/engineering/chief
icon_state = "rig-white"
@@ -331,7 +330,6 @@
desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish."
item_state = "ce_hardsuit"
sprite_sheets = null
sprite_sheets_obj = null
//Mining rig
/obj/item/clothing/head/helmet/space/rig/mining
@@ -412,6 +410,7 @@
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/wizard
icon_state = "rig-wiz"
@@ -424,6 +423,7 @@
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets = null
sprite_sheets_obj = null
//Medical Rig
/obj/item/clothing/head/helmet/space/rig/medical

View File

@@ -295,7 +295,7 @@
attack_self(mob/user)
if(user.r_hand == src || user.l_hand == src)
for(var/mob/O in viewers(user, null))
O.show_message(text("\red [] uses [] to comb their hair with incredible style and sophistication. What a guy.", user, src), 1)
O.show_message(text("\red [] uses [] to comb their hair with incredible style and sophistication. What a [].", user, src, user.gender == FEMALE ? "lady" : "guy"), 1)
return
/obj/item/weapon/fluff/hugo_cinderbacth_1 //thatoneguy: Hugo Cinderbatch

View File

@@ -23,6 +23,7 @@
possible_transfer_amounts = list(5)
volume = 5
can_be_placed_into = null
flags = FPRINT | TABLEPASS | OPENCONTAINER | NOBLUDGEON
/obj/item/weapon/reagent_containers/glass/rag/attack_self(mob/user as mob)
return

View File

@@ -147,7 +147,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(src.emagged)
dat += "<A href='?src=\ref[src];switchscreen=7'>7. Access the Forbidden Lore Vault</A><BR>"
if(src.arcanecheckout)
new /obj/item/weapon/tome(src.loc)
new /obj/item/weapon/book/tome(src.loc)
user << "<span class='warning'>Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.</span>"
user.visible_message("[user] stares at the blank screen for a few moments, his expression frozen in fear. When he finally awakens from it, he looks a lot older.", 2)
src.arcanecheckout = 0
@@ -329,26 +329,29 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(scanner.cache)
var/choice = input("Are you certain you wish to upload this title to the Archive?") in list("Confirm", "Abort")
if(choice == "Confirm")
establish_old_db_connection()
if(!dbcon_old.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
if(scanner.cache.unique)
alert("This book has been rejected from the database. Aborting!")
else
/*
var/sqltitle = dbcon.Quote(scanner.cache.name)
var/sqlauthor = dbcon.Quote(scanner.cache.author)
var/sqlcontent = dbcon.Quote(scanner.cache.dat)
var/sqlcategory = dbcon.Quote(upload_category)
*/
var/sqltitle = sanitizeSQL(scanner.cache.name)
var/sqlauthor = sanitizeSQL(scanner.cache.author)
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
var/sqlcategory = sanitizeSQL(upload_category)
var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO library (author, title, content, category) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]')")
if(!query.Execute())
usr << query.ErrorMsg()
establish_old_db_connection()
if(!dbcon_old.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
else
log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs")
alert("Upload Complete.")
/*
var/sqltitle = dbcon.Quote(scanner.cache.name)
var/sqlauthor = dbcon.Quote(scanner.cache.author)
var/sqlcontent = dbcon.Quote(scanner.cache.dat)
var/sqlcategory = dbcon.Quote(upload_category)
*/
var/sqltitle = sanitizeSQL(scanner.cache.name)
var/sqlauthor = sanitizeSQL(scanner.cache.author)
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
var/sqlcategory = sanitizeSQL(upload_category)
var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO library (author, title, content, category) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]')")
if(!query.Execute())
usr << query.ErrorMsg()
else
log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs")
alert("Upload Complete.")
if(href_list["targetid"])
var/sqlid = sanitizeSQL(href_list["targetid"])

View File

@@ -79,7 +79,7 @@
/mob/dead/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/tome))
if(istype(W,/obj/item/weapon/book/tome))
var/mob/dead/M = src
if(src.invisibility != 0)
M.invisibility = 0

View File

@@ -99,25 +99,29 @@
return
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0)
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
if(status_flags & GODMODE) return 0 //godmode
shock_damage *= siemens_coeff
if (shock_damage<1)
return 0
src.take_overall_damage(0,shock_damage,used_weapon="Electrocution")
//src.burn_skin(shock_damage)
//src.adjustFireLoss(shock_damage) //burn_skin will do this for us
//src.updatehealth()
src.visible_message(
"\red [src] was shocked by the [source]!", \
"\red <B>You feel a powerful shock course through your body!</B>", \
"\red You hear a heavy electrical crack." \
)
// if(src.stunned < shock_damage) src.stunned = shock_damage
Stun(10)//This should work for now, more is really silly and makes you lay there forever
// if(src.weakened < 20*siemens_coeff) src.weakened = 20*siemens_coeff
Weaken(10)
src.apply_damage(shock_damage, BURN, def_zone, used_weapon="Electrocution")
playsound(loc, "sparks", 50, 1, -1)
if (shock_damage > 10)
src.visible_message(
"\red [src] was shocked by the [source]!", \
"\red <B>You feel a powerful shock course through your body!</B>", \
"\red You hear a heavy electrical crack." \
)
Stun(10)//This should work for now, more is really silly and makes you lay there forever
Weaken(10)
else
src.visible_message(
"\red [src] was mildly shocked by the [source].", \
"\red You feel a mild shock course through your body.", \
"\red You hear a light zapping." \
)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, loc)

View File

@@ -531,13 +531,18 @@
if(wear_id)
return wear_id.GetID()
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/safety = 0)
if(!safety)
if(gloves)
var/obj/item/clothing/gloves/G = gloves
siemens_coeff = G.siemens_coefficient
return ..(shock_damage,source,siemens_coeff)
//Removed the horrible safety parameter. It was only being used by ninja code anyways.
//Now checks siemens_coefficient of the affected area by default
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null)
if(status_flags & GODMODE) return 0 //godmode
if (!def_zone)
def_zone = pick("l_hand", "r_hand")
var/datum/organ/external/affected_organ = get_organ(check_zone(def_zone))
var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ)
return ..(shock_damage, source, siemens_coeff, def_zone)
/mob/living/carbon/human/Topic(href, href_list)

View File

@@ -16,7 +16,7 @@ emp_act
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2, def_zone)
return 2
//Laserproof armour
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -59,7 +59,7 @@ emp_act
var/siemens_coeff = get_siemens_coefficient_organ(affected)
stun_amount *= siemens_coeff
agony_amount *= siemens_coeff
switch (def_zone)
if("head")
agony_amount *= 1.50
@@ -69,17 +69,17 @@ emp_act
c_hand = l_hand
else
c_hand = r_hand
if(c_hand && (stun_amount || agony_amount > 10))
msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect")
u_equip(c_hand)
if (affected.status & ORGAN_ROBOT)
emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!")
else
var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and")
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [affected.display_name]!")
..(stun_amount, agony_amount, def_zone)
/mob/living/carbon/human/getarmor(var/def_zone, var/type)
@@ -99,6 +99,19 @@ emp_act
organnum++
return (armorval/max(organnum, 1))
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone)
if (!def_zone)
return 1.0
var/siemens_coefficient = 1.0
var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
for(var/obj/item/clothing/C in clothing_items)
if(istype(C) && (C.body_parts_covered & def_zone.body_part)) // Is that body part being targeted covered?
siemens_coefficient *= C.siemens_coefficient
return siemens_coefficient
//this proc returns the armour value for a particular external organ.
/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type)
@@ -113,20 +126,6 @@ emp_act
protection += C.armor[type]
return protection
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone)
if (!def_zone)
return 1.0
var/siemens_coefficient = 1.0
var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
for(var/obj/item/clothing/C in clothing_items)
if(istype(C) && (C.body_parts_covered & def_zone.body_part)) // Is that body part being targeted covered?
siemens_coefficient *= C.siemens_coefficient
return siemens_coefficient
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
@@ -185,7 +184,7 @@ emp_act
if(!I || !user) return 0
var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src)
if(user == src) // Attacking yourself can't miss
target_zone = user.zone_sel.selecting
if(!target_zone)
@@ -275,17 +274,17 @@ emp_act
if(bloody)
bloody_body(src)
//Melee weapon embedded object code.
if (I.damtype == BRUTE && !I.is_robot_module())
var/damage = I.force
if (armor)
damage /= armor+1
//blunt objects should really not be embedding in things unless a huge amount of force is involved
var/embed_chance = weapon_sharp? damage/I.w_class : damage/(I.w_class*3)
var/embed_threshold = weapon_sharp? 5*I.w_class : 15*I.w_class
//Sharp objects will always embed if they do enough damage.
if((weapon_sharp && damage > (10*I.w_class)) || (damage > embed_threshold && prob(embed_chance)))
affecting.embed(I)
@@ -300,14 +299,14 @@ emp_act
var/obj/item/weapon/W = O
dtype = W.damtype
var/throw_damage = O.throwforce*(speed/5)
var/zone
if (istype(O.thrower, /mob/living))
var/mob/living/L = O.thrower
zone = check_zone(L.zone_sel.selecting)
else
zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest
//check if we hit
if (O.throw_source)
var/distance = get_dist(O.throw_source, loc)
@@ -318,15 +317,15 @@ emp_act
if(!zone)
visible_message("\blue \The [O] misses [src] narrowly!")
return
O.throwing = 0 //it hit, so stop moving
if ((O.thrower != src) && check_shields(throw_damage, "[O]"))
return
var/datum/organ/external/affecting = get_organ(zone)
var/hit_area = affecting.display_name
src.visible_message("\red [src] has been hit in the [hit_area] by [O].")
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here
@@ -350,16 +349,16 @@ emp_act
var/damage = throw_damage
if (armor)
damage /= armor+1
//blunt objects should really not be embedding in things unless a huge amount of force is involved
var/embed_chance = sharp? damage/I.w_class : damage/(I.w_class*3)
var/embed_threshold = sharp? 5*I.w_class : 15*I.w_class
//Sharp objects will always embed if they do enough damage.
//Thrown sharp objects have some momentum already and have a small chance to embed even if the damage is below the threshold
if((sharp && prob(damage/(10*I.w_class)*100)) || (damage > embed_threshold && prob(embed_chance)))
affecting.embed(I)
// Begin BS12 momentum-transfer code.
if(O.throw_source && speed >= 15)
var/obj/item/weapon/W = O

View File

@@ -291,7 +291,6 @@
if(H.mind)
H.mind.transfer_to(S)
S.key = H
for(var/mob/living/carbon/monkey/diona/D in H.contents)
if(D.client)

View File

@@ -14,6 +14,7 @@ var/list/department_radio_keys = list(
":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate",
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
":g" = "changeling", "#g" = "changeling", ".g" = "changeling",
":d" = "dronechat", "#d" = "dronechat", ".d" = "dronechat",
":R" = "right ear", "#R" = "right ear", ".R" = "right ear",
":L" = "left ear", "#L" = "left ear", ".L" = "left ear",
@@ -30,6 +31,7 @@ var/list/department_radio_keys = list(
":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate",
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
":G" = "changeling", "#G" = "changeling", ".G" = "changeling",
":D" = "dronechat", "#D" = "dronechat", ".D" = "dronechat",
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.

View File

@@ -110,7 +110,7 @@
return emote(copytext(message,2))
else if(length(message) >= 2)
if(copytext(message, 1 ,3) == ":d" || copytext(message, 1 ,3) == ":D")
if(parse_message_mode(message, "NONE") == "dronechat")
if(!is_component_functioning("radio"))
src << "\red Your radio transmitter isn't functional."

View File

@@ -281,10 +281,13 @@
/mob/living/silicon/robot/proc/updatename(var/prefix as text)
if(prefix)
modtype = prefix
if(istype(mmi, /obj/item/device/mmi/posibrain))
braintype = "Android"
if(mmi)
if(istype(mmi, /obj/item/device/mmi/posibrain))
braintype = "Android"
else
braintype = "Cyborg"
else
braintype = "Cyborg"
braintype = "Robot"
var/changed_name = ""
if(custom_name)
@@ -592,6 +595,10 @@
return
if (istype(W, /obj/item/weapon/weldingtool))
if (src == user)
user << "<span class='warning'>You lack the reach to be able to repair yourself.</span>"
return
if (!getBruteLoss())
user << "Nothing to fix here!"
return
@@ -1091,18 +1098,24 @@
/mob/living/silicon/robot/Topic(href, href_list)
..()
if(usr != src)
return
if (href_list["showalerts"])
robot_alerts()
return
if (href_list["mod"])
var/obj/item/O = locate(href_list["mod"])
if (O)
if (istype(O) && (O.loc == src))
O.attack_self(src)
if (href_list["act"])
var/obj/item/O = locate(href_list["act"])
if (!istype(O) || !(O in src.module.modules))
return
if(activated(O))
src << "Already activated"
return

View File

@@ -398,14 +398,14 @@
/obj/item/weapon/robot_module/drone
name = "drone module"
stacktypes = list(
/obj/item/stack/sheet/wood/cyborg = 1,
/obj/item/stack/sheet/mineral/plastic/cyborg = 1,
/obj/item/stack/sheet/rglass/cyborg = 5,
/obj/item/stack/sheet/wood = 1,
/obj/item/stack/sheet/mineral/plastic = 1,
/obj/item/stack/sheet/rglass = 5,
/obj/item/stack/tile/wood = 5,
/obj/item/stack/rods = 15,
/obj/item/stack/tile/plasteel = 15,
/obj/item/stack/sheet/metal/cyborg = 20,
/obj/item/stack/sheet/glass/cyborg = 20,
/obj/item/stack/sheet/metal = 20,
/obj/item/stack/sheet/glass = 20,
/obj/item/weapon/cable_coil = 30
)

View File

@@ -226,7 +226,9 @@
adjustBruteLoss(damage)
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
if(!Proj || Proj.nodamage)
return
adjustBruteLoss(Proj.damage)
return 0

View File

@@ -736,28 +736,23 @@ note dizziness decrements automatically in the mob's Life() proc.
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
var/is_movable
if(buckled && istype(buckled))
is_movable = buckled.movable
if(buckled && !is_movable)
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
pixel_y = V.mob_offset_y - 5
else
lying = 0
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled && (!buckled.movable))
anchored = 1
canmove = 0
if(istype(buckled,/obj/structure/stool/bed/chair) )
lying = 0
else if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(V.standing_mob)
lying = 0
else
lying = 1
else
lying = 1
else if(buckled && is_movable)
anchored = 0
canmove = 1
lying = 0
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
@@ -963,8 +958,7 @@ mob/proc/yank_out_object()
if(valid_objects.len == 1) //Yanking out last object - removing verb.
src.verbs -= /mob/proc/yank_out_object
if(istype(src,/mob/living/carbon/human))
if(ishuman(src))
var/mob/living/carbon/human/H = src
var/datum/organ/external/affected
@@ -975,7 +969,6 @@ mob/proc/yank_out_object()
affected.implants -= selection
H.shock_stage+=20
H.bloody_hands(S)
affected.take_damage((selection.w_class * 3), 0, 0, 1, "Embedded object extraction")
if(prob(selection.w_class * 5)) //I'M SO ANEMIC I COULD JUST -DIE-.
@@ -983,6 +976,10 @@ mob/proc/yank_out_object()
affected.wounds += I
H.custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
if (ishuman(U))
var/mob/living/carbon/human/human_user = U
human_user.bloody_hands(H)
selection.loc = get_turf(src)
for(var/obj/item/weapon/O in pinned)

View File

@@ -87,6 +87,8 @@
return 1
if (istype(other, src.type) || istype(src, other.type))
return 1
if(src.alien_talk_understand && other.alien_talk_understand)
return 1
return 0
//Language check.
@@ -159,4 +161,3 @@
return L
return null

View File

@@ -44,6 +44,7 @@
return
/obj/item/weapon/clipboard/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo))
user.drop_item()
W.loc = src
@@ -51,9 +52,11 @@
toppaper = W
user << "<span class='notice'>You clip the [W] onto \the [src].</span>"
update_icon()
else if(toppaper)
toppaper.attackby(usr.get_active_hand(), usr)
else if(istype(toppaper) && istype(W, /obj/item/weapon/pen))
toppaper.attackby(W, usr)
update_icon()
return
/obj/item/weapon/clipboard/attack_self(mob/user as mob)
@@ -85,32 +88,39 @@
if((usr.stat || usr.restrained()))
return
if(usr.contents.Find(src))
if(src.loc == usr)
if(href_list["pen"])
if(haspen)
if(istype(haspen) && (haspen.loc == src))
haspen.loc = usr.loc
usr.put_in_hands(haspen)
haspen = null
if(href_list["addpen"])
else if(href_list["addpen"])
if(!haspen)
if(istype(usr.get_active_hand(), /obj/item/weapon/pen))
var/obj/item/weapon/pen/W = usr.get_active_hand()
var/obj/item/weapon/pen/W = usr.get_active_hand()
if(istype(W, /obj/item/weapon/pen))
usr.drop_item()
W.loc = src
haspen = W
usr << "<span class='notice'>You slot the pen into \the [src].</span>"
if(href_list["write"])
var/obj/item/P = locate(href_list["write"])
if(P)
if(usr.get_active_hand())
P.attackby(usr.get_active_hand(), usr)
else if(href_list["write"])
var/obj/item/weapon/P = locate(href_list["write"])
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) && (P == toppaper) )
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/pen))
P.attackby(I, usr)
if(href_list["remove"])
else if(href_list["remove"])
var/obj/item/P = locate(href_list["remove"])
if(P)
if(P && (P.loc == src) && (istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/photo)) )
P.loc = usr.loc
usr.put_in_hands(P)
if(P == toppaper)
@@ -121,9 +131,11 @@
else
toppaper = null
if(href_list["read"])
else if(href_list["read"])
var/obj/item/weapon/paper/P = locate(href_list["read"])
if(P)
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) )
if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon)))
usr << browse("<HTML><HEAD><TITLE>[P.name]</TITLE></HEAD><BODY>[stars(P.info)][P.stamps]</BODY></HTML>", "window=[P.name]")
onclose(usr, "[P.name]")
@@ -131,18 +143,18 @@
usr << browse("<HTML><HEAD><TITLE>[P.name]</TITLE></HEAD><BODY>[P.info][P.stamps]</BODY></HTML>", "window=[P.name]")
onclose(usr, "[P.name]")
if(href_list["look"])
else if(href_list["look"])
var/obj/item/weapon/photo/P = locate(href_list["look"])
if(P)
if(P && (P.loc == src) && istype(P, /obj/item/weapon/photo) )
P.show(usr)
if(href_list["top"])
else if(href_list["top"]) // currently unused
var/obj/item/P = locate(href_list["top"])
if(P)
if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) )
toppaper = P
usr << "<span class='notice'>You move [P.name] to the top.</span>"
//Update everything
attack_self(usr)
update_icon()
return
return

View File

@@ -57,9 +57,7 @@
user.set_machine(src)
var/dat = "<center><table>"
var/i
for(i=contents.len, i>=1, i--)
var/obj/item/P = contents[i]
for(var/obj/item/P in src)
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
dat += "</table></center>"
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
@@ -89,12 +87,13 @@
//var/retrieveindex = text2num(href_list["retrieve"])
var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex]
if(P && in_range(src, usr))
if(istype(P) && (P.loc == src) && src.Adjacent(usr))
usr.put_in_hands(P)
updateUsrDialog()
icon_state = "[initial(icon_state)]-open"
sleep(5)
icon_state = initial(icon_state)
spawn(0)
sleep(5)
icon_state = initial(icon_state)
/*

View File

@@ -59,34 +59,34 @@
if((usr.stat || usr.restrained()))
return
if(usr.contents.Find(src))
if(src.loc == usr)
if(href_list["remove"])
var/obj/item/P = locate(href_list["remove"])
if(P && P.loc == src)
if(P && (P.loc == src) && istype(P))
P.loc = usr.loc
usr.put_in_hands(P)
if(href_list["read"])
else if(href_list["read"])
var/obj/item/weapon/paper/P = locate(href_list["read"])
if(P)
if(P && (P.loc == src) && istype(P))
if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon)))
usr << browse("<HTML><HEAD><TITLE>[P.name]</TITLE></HEAD><BODY>[stars(P.info)][P.stamps]</BODY></HTML>", "window=[P.name]")
onclose(usr, "[P.name]")
else
usr << browse("<HTML><HEAD><TITLE>[P.name]</TITLE></HEAD><BODY>[P.info][P.stamps]</BODY></HTML>", "window=[P.name]")
onclose(usr, "[P.name]")
if(href_list["look"])
else if(href_list["look"])
var/obj/item/weapon/photo/P = locate(href_list["look"])
if(P)
if(P && (P.loc == src) && istype(P))
P.show(usr)
if(href_list["browse"])
else if(href_list["browse"])
var/obj/item/weapon/paper_bundle/P = locate(href_list["browse"])
if(P)
if(P && (P.loc == src) && istype(P))
P.attack_self(usr)
onclose(usr, "[P.name]")
//Update everything
attack_self(usr)
update_icon()
return
return

View File

@@ -113,6 +113,22 @@
user.visible_message("<span class='notice'>You show the paper to [M]. </span>", \
"<span class='notice'> [user] holds up a paper and shows it to [M]. </span>")
M << examine()
else if(user.zone_sel.selecting == "mouth") // lipstick wiping
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H == user)
user << "<span class='notice'>You wipe off the lipstick with [src].</span>"
H.lip_style = null
H.update_body()
else
user.visible_message("<span class='warning'>[user] begins to wipe [H]'s lipstick off with \the [src].</span>", \
"<span class='notice'>You begin to wipe off [H]'s lipstick.</span>")
if(do_after(user, 10) && do_after(H, 10, 5, 0)) //user needs to keep their active hand, H does not.
user.visible_message("<span class='notice'>[user] wipes [H]'s lipstick off with \the [src].</span>", \
"<span class='notice'>You wipe off [H]'s lipstick.</span>")
H.lip_style = null
H.update_body()
/obj/item/weapon/paper/proc/addtofield(var/id, var/text, var/links = 0)
var/locid = 0
@@ -294,7 +310,8 @@
iscrayon = 1
if((!in_range(src, usr) && loc != usr && !( istype(loc, /obj/item/weapon/clipboard) ) && loc.loc != usr && usr.get_active_hand() != i)) // Some check to see if he's allowed to write
// if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr
if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/weapon/clipboard) || istype(src.loc, /obj/item/weapon/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) )
return
/*
t = checkhtml(t)

View File

@@ -513,6 +513,9 @@
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
//This is for performance optimization only.
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.gloves)

View File

@@ -84,6 +84,7 @@
if(!..()) return //Only do this on a successful shot.
icon_state = "crossbow"
tension = 0
/obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob)
if(tension)

View File

@@ -2081,25 +2081,29 @@ datum
description = "This is what makes chilis hot."
reagent_state = LIQUID
color = "#B31008" // rgb: 179, 16, 8
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 15)
M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("frostoil"))
holder.remove_reagent("frostoil", 5)
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(5,20)
if(15 to 25)
M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(10,20)
if(25 to INFINITY)
M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT
if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(15,20)
if(!M)
M = holder.my_atom
if(!data)
data = 1
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species && !(H.species.flags & (NO_PAIN | IS_SYNTHETIC)) )
switch(data)
if(1 to 2)
H << "\red <b>Your insides feel uncomfortably hot !</b>"
if(2 to 20)
if(prob(5))
H << "\red <b>Your insides feel uncomfortably hot !</b>"
if(20 to INFINITY)
H.apply_effect(2,AGONY,0)
if(prob(5))
H.visible_message("<span class='warning'>[H] [pick("dry heaves!","coughs!","splutters!")]</span>")
H << "\red <b>You feel like your insides are burning !</b>"
else if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(10,25)
holder.remove_reagent("frostoil", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
data++
..()
@@ -2165,10 +2169,29 @@ datum
victim.Weaken(5)
//victim.Paralyse(10)
//victim.drop_item()
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(prob(5))
M.visible_message("<span class='warning'>[M] [pick("dry heaves!","coughs!","splutters!")]</span>")
if(!M)
M = holder.my_atom
if(!data)
data = 1
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species && !(H.species.flags & (NO_PAIN | IS_SYNTHETIC)) )
switch(data)
if(1)
H << "\red <b>You feel like your insides are burning !</b>"
if(2 to INFINITY)
H.apply_effect(4,AGONY,0)
if(prob(5))
H.visible_message("<span class='warning'>[H] [pick("dry heaves!","coughs!","splutters!")]</span>")
H << "\red <b>You feel like your insides are burning !</b>"
else if(istype(M, /mob/living/carbon/slime))
M.bodytemperature += rand(15,30)
holder.remove_reagent("frostoil", 5)
holder.remove_reagent(src.id, FOOD_METABOLISM)
data++
..()
return
frostoil
@@ -3063,6 +3086,9 @@ datum
paperaffected.clearpaper()
usr << "The solution dissolves the ink on the paper."
if(istype(O,/obj/item/weapon/book))
if(istype(O,/obj/item/weapon/book/tome))
usr << "The solution does nothing. Whatever this is, it isn't normal ink."
return
if(volume >= 5)
var/obj/item/weapon/book/affectedbook = O
affectedbook.dat = null

View File

@@ -605,8 +605,8 @@
center_of_mass = list("x"=16, "y"=10)
else
icon_state = "glass_empty"
name = "Drinking glass"
desc = "Your standard drinking glass"
name = "glass"
desc = "Your standard drinking glass."
center_of_mass = list("x"=16, "y"=10)
return

View File

@@ -147,6 +147,10 @@
/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if(istype(Proj.firer))
message_admins("[key_name_admin(Proj.firer)] shot fueltank at ([loc.x],[loc.y],[loc.z]).")
log_game("[key_name(Proj.firer)] shot fueltank at ([loc.x],[loc.y],[loc.z]).")
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
explode()

View File

@@ -0,0 +1,146 @@
/datum/shuttle/ferry/escape_pod
var/datum/computer/file/embedded_program/docking/simple/escape_pod/arming_controller
/datum/shuttle/ferry/escape_pod/can_launch()
if(arming_controller && !arming_controller.armed) //must be armed
return 0
if(location)
return 0 //it's a one-way trip.
return ..()
/datum/shuttle/ferry/escape_pod/can_force()
if (arming_controller.eject_time && world.time < arming_controller.eject_time + 50)
return 0 //dont allow force launching until 5 seconds after the arming controller has reached it's countdown
return ..()
/datum/shuttle/ferry/escape_pod/can_cancel()
return 0
//This controller goes on the escape pod itself
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod
name = "escape pod controller"
var/datum/shuttle/ferry/escape_pod/pod
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data = list(
"docking_status" = docking_program.get_docking_status(),
"override_enabled" = docking_program.override_enabled,
"door_state" = docking_program.memory["door_status"]["state"],
"door_lock" = docking_program.memory["door_status"]["lock"],
"can_force" = pod.can_force() || (emergency_shuttle.departed && pod.can_launch()), //allow players to manually launch ahead of time if the shuttle leaves
"is_armed" = pod.arming_controller.armed,
)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "escape_pod_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/Topic(href, href_list)
if(..()) //I hate this "return 1 to indicate they are not allowed to use the controller" crap, but not sure how else to do it without being able to call machinery/Topic() directly.
return 1
if("manual_arm")
pod.arming_controller.arm()
if("force_launch")
if (pod.can_force())
pod.force_launch(src)
else if (emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves
pod.launch(src)
return 0
//This controller is for the escape pod berth (station side)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth
name = "escape pod berth controller"
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/initialize()
..()
docking_program = new/datum/computer/file/embedded_program/docking/simple/escape_pod(src)
program = docking_program
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/armed = null
if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod))
var/datum/computer/file/embedded_program/docking/simple/escape_pod/P = docking_program
armed = P.armed
data = list(
"docking_status" = docking_program.get_docking_status(),
"override_enabled" = docking_program.override_enabled,
"armed" = armed,
)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "escape_pod_berth_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/card/emag) && !emagged)
user << "\blue You emag the [src], arming the escape pod!"
emagged = 1
if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod))
var/datum/computer/file/embedded_program/docking/simple/escape_pod/P = docking_program
if (!P.armed)
P.arm()
return
..()
//A docking controller program for a simple door based docking port
/datum/computer/file/embedded_program/docking/simple/escape_pod
var/armed = 0
var/eject_delay = 10 //give latecomers some time to get out of the way if they don't make it onto the pod
var/eject_time = null
var/closing = 0
/datum/computer/file/embedded_program/docking/simple/escape_pod/proc/arm()
armed = 1
open_door()
/datum/computer/file/embedded_program/docking/simple/escape_pod/receive_user_command(command)
if (!armed)
return
..(command)
/datum/computer/file/embedded_program/docking/simple/escape_pod/process()
..()
if (eject_time && world.time >= eject_time && !closing)
close_door()
closing = 1
/datum/computer/file/embedded_program/docking/simple/escape_pod/prepare_for_docking()
return
/datum/computer/file/embedded_program/docking/simple/escape_pod/ready_for_docking()
return 1
/datum/computer/file/embedded_program/docking/simple/escape_pod/finish_docking()
return //don't do anything - the doors only open when the pod is armed.
/datum/computer/file/embedded_program/docking/simple/escape_pod/prepare_for_undocking()
eject_time = world.time + eject_delay*10
/*
/datum/computer/file/embedded_program/docking/simple/escape_pod/ready_for_undocking()
if (world.time < eject_time)
return 0
return ..()
*/

View File

@@ -223,38 +223,13 @@
if(..())
return
if(href_list["auth"])
/*
//This doesn't work at all.
if (!emagged && href_list["auth"] == -1)
//They selected an empty entry. Try to scan their id.
if (ishuman(usr))
var/mob/living/carbon/human/H = usr
if (!read_authorization(H.get_active_hand())) //try to read what's in their hand first
read_authorization(H.wear_id)
else
*/
//remove the authorization
var/dna_hash = href_list["auth"]
if(href_list["removeid"])
var/dna_hash = href_list["removeid"]
authorized -= dna_hash
/datum/shuttle/ferry/escape_pod
var/datum/computer/file/embedded_program/docking/simple/escape_pod/arming_controller
/datum/shuttle/ferry/escape_pod/can_launch()
if(arming_controller && !arming_controller.armed)
return 0
if(location)
return 0 //it's a one-way trip.
return ..()
/datum/shuttle/ferry/escape_pod/can_force()
if (arming_controller.eject_time && world.time < arming_controller.eject_time + 50)
return 0 //dont allow force launching until 5 seconds after the arming controller has reached it's countdown
return ..()
/datum/shuttle/ferry/escape_pod/can_cancel()
return 0
if(!emagged && href_list["scanid"])
//They selected an empty entry. Try to scan their id.
if (ishuman(usr))
var/mob/living/carbon/human/H = usr
if (!read_authorization(H.get_active_hand())) //try to read what's in their hand first
read_authorization(H.wear_id)

View File

@@ -141,11 +141,13 @@
if(damage > explosion_point)
for(var/mob/living/mob in living_mob_list)
if(istype(mob, /mob/living/carbon/human))
//Hilariously enough, running into a closet should make you get hit the hardest.
mob:hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) )
mob.apply_effect(rads, IRRADIATE)
if(loc.z == mob.loc.z)
if(istype(mob, /mob/living/carbon/human))
//Hilariously enough, running into a closet should make you get hit the hardest.
var/mob/living/carbon/human/H = mob
H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) )
mob.apply_effect(rads, IRRADIATE)
explode()
else
@@ -328,10 +330,15 @@
if(is_type_in_list(X, uneatable)) continue
if(((X) && (!istype(X,/mob/living/carbon/human))))
step_towards(X,src)
if(!X:anchored) //unanchored objects pulled twice as fast
if(istype(X, /obj)) //unanchored objects pulled twice as fast
var/obj/O = X
if(!O.anchored)
step_towards(X,src)
else
step_towards(X,src)
if(istype(X, /obj/structure/window)) //shatter windows
X.ex_act(2.0)
var/obj/structure/window/W = X
W.ex_act(2.0)
else if(istype(X,/mob/living/carbon/human))
var/mob/living/carbon/human/H = X
if(istype(H.shoes,/obj/item/clothing/shoes/magboots))

View File

@@ -7,10 +7,9 @@
powered = 1
locked = 0
standing_mob = 1
load_item_visible = 1
load_offset_x = 0
load_offset_y = 7
mob_offset_y = 7
var/car_limit = 3 //how many cars an engine can pull before performance degrades
active_engines = 1
@@ -31,10 +30,10 @@
passenger_allowed = 0
locked = 0
standing_mob = 1
load_item_visible = 1
load_offset_x = 0
load_offset_y = 4
mob_offset_y = 8
//-------------------------------------------
// Standard procs
@@ -43,13 +42,13 @@
..()
cell = new /obj/item/weapon/cell/high
verbs -= /atom/movable/verb/pull
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
key = new()
var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
overlays += I
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/cargo/engine/Move()
if(on && cell.charge < power_use)
if(on && cell.charge < charge_use)
turn_off()
update_stats()
if(load && is_train_head())
@@ -117,6 +116,25 @@
..()
update_stats()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(on)
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
/obj/vehicle/train/cargo/engine/turn_off()
..()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(!on)
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
/obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
@@ -149,7 +167,7 @@
return 0
if(is_train_head())
if(direction == reverse_direction(dir))
if(direction == reverse_direction(dir) && tow)
return 0
if(Move(get_step(src, direction)))
return 1
@@ -165,20 +183,7 @@
if(get_dist(usr,src) <= 1)
usr << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
/obj/vehicle/train/cargo/engine/verb/check_power()
set name = "Check power level"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!cell)
usr << "There is no power cell installed in [src]."
return
usr << "The power meter reads [round(cell.percent(), 0.01)]%"
usr << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%"
/obj/vehicle/train/cargo/engine/verb/start_engine()
set name = "Start engine"
@@ -195,10 +200,8 @@
turn_on()
if (on)
usr << "You start [src]'s engine."
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
else
if(cell.charge < power_use)
if(cell.charge < charge_use)
usr << "[src] is out of power."
else
usr << "[src]'s engine won't start."
@@ -218,8 +221,6 @@
turn_off()
if (!on)
usr << "You stop [src]'s engine."
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
/obj/vehicle/train/cargo/engine/verb/remove_key()
set name = "Remove key"
@@ -252,10 +253,7 @@
return 0
..()
if(istype(load, /mob/living/carbon/human))
load.pixel_y += 4
if(load)
return 1
@@ -277,13 +275,22 @@
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/cargo/engine/update_train_stats()
..()
/obj/vehicle/train/cargo/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
update_move_delay()
//Update move delay
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/cargo/trolley/update_train_stats()
..()
/obj/vehicle/train/cargo/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
if(!lead && !tow)
anchored = 0
@@ -294,12 +301,3 @@
else
anchored = 1
verbs -= /atom/movable/verb/pull
/obj/vehicle/train/cargo/engine/proc/update_move_delay()
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.05 //makes cargo trains 5% slower than running when not overweight

View File

@@ -32,6 +32,8 @@
tow.Move(old_loc)
return 1
else
if(lead)
unattach()
return 0
/obj/vehicle/train/Bump(atom/Obstacle)
@@ -48,14 +50,23 @@
if(istype(A, /mob/living))
var/mob/living/M = A
visible_message("\red [src] knocks over [M]!")
M.apply_effects(5, 5) //knock people down if you hit them
M.apply_damages(5 * train_length / move_delay) // and do damage according to how fast the train is going and how heavy it is
M.apply_effects(5, 5) //knock people down if you hit them
M.apply_damages(22 / move_delay) // and do damage according to how fast the train is going
if(istype(load, /mob/living/carbon/human))
var/mob/living/D = load
D << "\red You hit [M]!"
msg_admin_attack("[D.name] ([D.ckey]) hit [M.name] ([M.ckey]) with [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
//-------------------------------------------
// Vehicle procs
//-------------------------------------------
/obj/vehicle/train/explode()
if (tow)
tow.unattach()
unattach()
..()
//-------------------------------------------
// Interaction procs
@@ -79,7 +90,7 @@
return 1
/obj/vehicle/train/MouseDrop_T(var/atom/movable/C, mob/user as mob)
if(user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C))
if(user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !user.canmove))
return
if(istype(C,/obj/vehicle/train))
latch(C, user)
@@ -132,6 +143,15 @@
if (T.tow)
user << "\red [T] is already towing something."
return
//check for cycles.
var/obj/vehicle/train/next_car = T
while (next_car)
if (next_car == src)
user << "\red That seems very silly."
return
next_car = next_car.lead
//latch with src as the follower
lead = T
T.tow = src
@@ -182,23 +202,28 @@
// size of the train, to limit super long trains.
//-------------------------------------------------------
/obj/vehicle/train/update_stats()
if(tow)
return tow.update_stats() //take us to the very end
else
update_train_stats() //we're at the end
//first, seek to the end of the train
var/obj/vehicle/train/T = src
while(T.tow)
//check for cyclic train.
if (T.tow == src)
lead.tow = null
lead.update_stats()
lead = null
update_stats()
return
T = T.tow
/obj/vehicle/train/proc/update_train_stats()
if(powered && on)
active_engines = 1 //increment active engine count if this is a running engine
else
active_engines = 0
//now walk back to the front.
var/active_engines = 0
var/train_length = 0
while(T)
train_length++
if (powered && on)
active_engines++
T.update_car(train_length, active_engines)
T = T.lead
train_length = 1
if(istype(tow))
active_engines += tow.active_engines
train_length += tow.train_length
//update the next section of train ahead of us
if(istype(lead))
lead.update_train_stats()
/obj/vehicle/train/proc/update_car(var/train_length, var/active_engines)
return

View File

@@ -22,13 +22,13 @@
var/movable = 1
var/obj/item/weapon/cell/cell
var/power_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/standing_mob = 0 //if a mob loaded on the vehicle should be standing
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
var/load_offset_x = 0 //pixel_x offset for item overlay
var/load_offset_y = 0 //pixel_y offset for item overlay
var/mob_offset_y = 0 //pixel_y offset for mob overlay
//-------------------------------------------
// Standard procs
@@ -39,16 +39,20 @@
/obj/vehicle/Move()
if(world.time > l_move_time + move_delay)
if(on && powered && cell.charge < power_use)
if(on && powered && cell.charge < charge_use)
turn_off()
var/init_anc = anchored
anchored = 0
if(..())
if(on && powered)
cell.use(power_use)
if(!..())
anchored = init_anc
return 0
anchored = init_anc
if(on && powered)
cell.use(charge_use)
if(load)
load.forceMove(loc)// = loc
load.dir = dir
@@ -168,7 +172,7 @@
/obj/vehicle/proc/turn_on()
if(stat)
return 0
if(powered && cell.charge < power_use)
if(powered && cell.charge < charge_use)
return 0
on = 1
luminosity = initial(luminosity)
@@ -200,6 +204,11 @@
cell.update_icon()
cell = null
//stuns people who are thrown off a train that has been blown up
if(istype(load, /mob/living))
var/mob/living/M = load
M.apply_effects(5, 5)
unload()
new /obj/effect/gibspawner/robot(Tsec)
@@ -219,7 +228,7 @@
turn_off()
return
if(cell.charge < power_use)
if(cell.charge < charge_use)
turn_off()
return
@@ -280,7 +289,10 @@
if(load_item_visible)
C.pixel_x += load_offset_x
C.pixel_y += load_offset_y
if(ismob(C))
C.pixel_y += mob_offset_y
else
C.pixel_y += load_offset_y
C.layer = layer + 0.1 //so it sits above the vehicle
if(ismob(C))