Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into powernet-sensors-mk2

This commit is contained in:
Atlantiscze
2014-11-19 13:15:40 +01:00
296 changed files with 3229 additions and 4082 deletions
+1 -1
View File
@@ -181,7 +181,7 @@
name = "Scientist"
corpseradio = /obj/item/device/radio/headset/headset_sci
corpseuniform = /obj/item/clothing/under/rank/scientist
corpsesuit = /obj/item/clothing/suit/storage/labcoat/science
corpsesuit = /obj/item/clothing/suit/storage/toggle/labcoat/science
corpseback = /obj/item/weapon/storage/backpack
corpseshoes = /obj/item/clothing/shoes/white
corpseid = 1
+5 -5
View File
@@ -18,13 +18,13 @@ var/global/list/gear_datums = list()
//create a list of gear datums to sort
for(var/type in typesof(/datum/gear)-/datum/gear)
var/datum/gear/G = new type()
var/category = (G.sort_category in sort_categories)? G.sort_category : "unknown"
sort_categories[category][G.display_name] = G
for (var/category in sort_categories)
gear_datums.Add(sortAssoc(sort_categories[category]))
return 1
/datum/gear
@@ -475,13 +475,13 @@ var/global/list/gear_datums = list()
/datum/gear/brown_jacket
display_name = "leather jacket, brown"
path = /obj/item/clothing/suit/storage/brown_jacket
path = /obj/item/clothing/suit/storage/toggle/brown_jacket
cost = 3
slot = slot_wear_suit
/datum/gear/brown_jacket_nt
display_name = "leather jacket, NanoTrasen, brown"
path = /obj/item/clothing/suit/storage/brown_jacket/nanotrasen
path = /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen
cost = 3
slot = slot_wear_suit
+22 -1
View File
@@ -10,6 +10,17 @@ var/list/spawntypes = list()
var/msg //Message to display on the arrivals computer.
var/list/turfs //List of turfs to spawn on.
var/display_name //Name used in preference setup.
var/list/restrict_job = null
var/list/disallow_job = null
proc/check_job_spawning(job)
if(restrict_job && !(job in restrict_job))
return 0
if(disallow_job && (job in disallow_job))
return 0
return 1
/datum/spawnpoint/arrivals
display_name = "Arrivals Shuttle"
@@ -30,7 +41,17 @@ var/list/spawntypes = list()
/datum/spawnpoint/cryo
display_name = "Cryogenic Storage"
msg = "has completed cryogenic revival"
disallow_job = list("Cyborg")
/datum/spawnpoint/cryo/New()
..()
turfs = latejoin_cryo
turfs = latejoin_cryo
/datum/spawnpoint/cyborg
display_name = "Cyborg Storage"
msg = "has been activated from storage"
restrict_job = list("Cyborg")
/datum/spawnpoint/cyborg/New()
..()
turfs = latejoin_cyborg
+5 -1
View File
@@ -82,7 +82,11 @@
icon_state = "swathelm"
item_state = "helmet"
flags = FPRINT|TABLEPASS|HEADCOVERSEYES
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
)
armor = list(melee = 62, bullet = 50, laser = 50,energy = 35, bomb = 10, bio = 2, rad = 0)
flags_inv = HIDEEARS
siemens_coefficient = 0.7
+8
View File
@@ -7,6 +7,10 @@
flags_inv = HIDEFACE
body_parts_covered = FACE
w_class = 2
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
)
/obj/item/clothing/mask/balaclava/tactical
name = "green balaclava"
@@ -16,6 +20,10 @@
flags = FPRINT|TABLEPASS|BLOCKHAIR
flags_inv = HIDEFACE
w_class = 2
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
)
/obj/item/clothing/mask/luchador
name = "Luchador Mask"
+5 -8
View File
@@ -8,14 +8,11 @@
w_class = 2
gas_transfer_coefficient = 0.90
//Monkeys can not take the muzzle off of themself! Call PETA!
/obj/item/clothing/mask/muzzle/attack_paw(mob/user as mob)
if (src == user.wear_mask)
return
else
..()
return
// Clumsy folks can't take the mask off themselves.
/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
if(user.wear_mask == src && !user.IsAdvancedToolUser())
return 0
..()
/obj/item/clothing/mask/surgical
name = "sterile mask"
+1 -5
View File
@@ -27,13 +27,9 @@
icon_state = "ert_commander"
item_state = "suit-command"
w_class = 3
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen)
slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
/obj/item/weapon/gun/energy/taser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, /obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/handcuffs, /obj/item/weapon/storage/briefcase/inflatable)
siemens_coefficient = 0.6
//Commander
+9 -38
View File
@@ -141,11 +141,13 @@
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
//Lawyer
/obj/item/clothing/suit/storage/lawyer/bluejacket
/obj/item/clothing/suit/storage/toggle/lawyer/bluejacket
name = "Blue Suit Jacket"
desc = "A snappy dress jacket."
icon_state = "suitjacket_blue_open"
item_state = "suitjacket_blue_open"
icon_open = "suitjacket_blue_open"
icon_closed = "suitjacket_blue"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
@@ -158,62 +160,31 @@
body_parts_covered = UPPER_TORSO|ARMS
//Internal Affairs
/obj/item/clothing/suit/storage/internalaffairs
/obj/item/clothing/suit/storage/toggle/internalaffairs
name = "Internal Affairs Jacket"
desc = "A smooth black jacket."
icon_state = "ia_jacket_open"
item_state = "ia_jacket"
icon_open = "ia_jacket_open"
icon_closed = "ia_jacket"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
verb/toggle()
set name = "Toggle Coat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
switch(icon_state)
if("ia_jacket_open")
src.icon_state = "ia_jacket"
usr << "You button up the jacket."
if("ia_jacket")
src.icon_state = "ia_jacket_open"
usr << "You unbutton the jacket."
else
usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are."
return
update_clothing_icon() //so our overlays update
//Medical
/obj/item/clothing/suit/storage/fr_jacket
/obj/item/clothing/suit/storage/toggle/fr_jacket
name = "first responder jacket"
desc = "A high-visibility jacket worn by medical first responders."
icon_state = "fr_jacket_open"
item_state = "fr_jacket"
icon_open = "fr_jacket_open"
icon_closed = "fr_jacket"
blood_overlay_type = "armor"
allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen)
body_parts_covered = UPPER_TORSO|ARMS
verb/toggle()
set name = "Toggle Jacket Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
switch(icon_state)
if("fr_jacket_open")
src.icon_state = "fr_jacket"
usr << "You button up the jacket."
if("fr_jacket")
src.icon_state = "fr_jacket_open"
usr << "You unbutton the jacket."
update_clothing_icon() //so our overlays update
//Mime
/obj/item/clothing/suit/suspenders
name = "suspenders"
+39 -106
View File
@@ -1,171 +1,104 @@
/obj/item/clothing/suit/storage/labcoat
/obj/item/clothing/suit/storage/toggle/labcoat
name = "labcoat"
desc = "A suit that protects against minor chemical spills."
icon_state = "labcoat_open"
item_state = "labcoat" //Is this even used for anything?
icon_open = "labcoat_open"
icon_closed = "labcoat"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper)
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
verb/toggle()
set name = "Toggle Labcoat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
//Why???
switch(icon_state)
if("labcoat_open")
src.icon_state = "labcoat"
usr << "You button up the labcoat."
if("labcoat")
src.icon_state = "labcoat_open"
usr << "You unbutton the labcoat."
if("red_labcoat_open")
src.icon_state = "red_labcoat"
usr << "You button up the labcoat."
if("red_labcoat")
src.icon_state = "red_labcoat_open"
usr << "You unbutton the labcoat."
if("blue_labcoat_open")
src.icon_state = "blue_labcoat"
usr << "You button up the labcoat."
if("blue_labcoat")
src.icon_state = "blue_labcoat_open"
usr << "You unbutton the labcoat."
if("purple_labcoat_open")
src.icon_state = "purple_labcoat"
usr << "You button up the labcoat."
if("purple_labcoat")
src.icon_state = "purple_labcoat_open"
usr << "You unbutton the labcoat."
if("green_labcoat_open")
src.icon_state = "green_labcoat"
usr << "You button up the labcoat."
if("green_labcoat")
src.icon_state = "green_labcoat_open"
usr << "You unbutton the labcoat."
if("orange_labcoat_open")
src.icon_state = "orange_labcoat"
usr << "You button up the labcoat."
if("orange_labcoat")
src.icon_state = "orange_labcoat_open"
usr << "You unbutton the labcoat."
if("labcoat_cmo_open")
src.icon_state = "labcoat_cmo"
usr << "You button up the labcoat."
if("labcoat_cmo")
src.icon_state = "labcoat_cmo_open"
usr << "You unbutton the labcoat."
if("labcoat_cmoalt_open")
src.icon_state = "labcoat_cmoalt"
usr << "You button up the labcoat."
if("labcoat_cmoalt")
src.icon_state = "labcoat_cmoalt_open"
usr << "You unbutton the labcoat."
if("labcoat_gen_open")
src.icon_state = "labcoat_gen"
usr << "You button up the labcoat."
if("labcoat_gen")
src.icon_state = "labcoat_gen_open"
usr << "You unbutton the labcoat."
if("labcoat_chem_open")
src.icon_state = "labcoat_chem"
usr << "You button up the labcoat."
if("labcoat_chem")
src.icon_state = "labcoat_chem_open"
usr << "You unbutton the labcoat."
if("labcoat_vir_open")
src.icon_state = "labcoat_vir"
usr << "You button up the labcoat."
if("labcoat_vir")
src.icon_state = "labcoat_vir_open"
usr << "You unbutton the labcoat."
if("labcoat_tox_open")
src.icon_state = "labcoat_tox"
usr << "You button up the labcoat."
if("labcoat_tox")
src.icon_state = "labcoat_tox_open"
usr << "You unbutton the labcoat."
if("labgreen_open")
src.icon_state = "labgreen"
usr << "You button up the labcoat."
if("labgreen")
src.icon_state = "labgreen_open"
usr << "You unbutton the labcoat."
else
usr << "You attempt to button-up the velcro on your [src], before promptly realising how silly you are."
return
update_clothing_icon() //so our overlays update
/obj/item/clothing/suit/storage/labcoat/red
/obj/item/clothing/suit/storage/toggle/labcoat/red
name = "red labcoat"
desc = "A suit that protects against minor chemical spills. This one is red."
icon_state = "red_labcoat_open"
item_state = "red_labcoat"
icon_open = "red_labcoat_open"
icon_closed = "red_labcoat"
/obj/item/clothing/suit/storage/labcoat/blue
/obj/item/clothing/suit/storage/toggle/labcoat/blue
name = "blue labcoat"
desc = "A suit that protects against minor chemical spills. This one is blue."
icon_state = "blue_labcoat_open"
item_state = "blue_labcoat"
icon_open = "blue_labcoat_open"
icon_closed = "blue_labcoat"
/obj/item/clothing/suit/storage/labcoat/purple
/obj/item/clothing/suit/storage/toggle/labcoat/purple
name = "purple labcoat"
desc = "A suit that protects against minor chemical spills. This one is purple."
icon_state = "purple_labcoat_open"
item_state = "purple_labcoat"
icon_open = "purple_labcoat_open"
icon_closed = "purple_labcoat"
/obj/item/clothing/suit/storage/labcoat/orange
/obj/item/clothing/suit/storage/toggle/labcoat/orange
name = "orange labcoat"
desc = "A suit that protects against minor chemical spills. This one is orange."
icon_state = "orange_labcoat_open"
item_state = "orange_labcoat"
icon_open = "orange_labcoat_open"
icon_closed = "orange_labcoat"
/obj/item/clothing/suit/storage/labcoat/green
/obj/item/clothing/suit/storage/toggle/labcoat/green
name = "green labcoat"
desc = "A suit that protects against minor chemical spills. This one is green."
icon_state = "green_labcoat_open"
item_state = "green_labcoat"
icon_open = "green_labcoat_open"
icon_closed = "green_labcoat"
/obj/item/clothing/suit/storage/labcoat/cmo
/obj/item/clothing/suit/storage/toggle/labcoat/cmo
name = "chief medical officer's labcoat"
desc = "Bluer than the standard model."
icon_state = "labcoat_cmo_open"
item_state = "labcoat_cmo"
icon_open = "labcoat_cmo_open"
icon_closed = "labcoat_cmo"
/obj/item/clothing/suit/storage/labcoat/cmoalt
/obj/item/clothing/suit/storage/toggle/labcoat/cmoalt
name = "chief medical officer labcoat"
desc = "A labcoat with command blue highlights."
icon_state = "labcoat_cmoalt_open"
icon_open = "labcoat_cmoalt_open"
icon_closed = "labcoat_cmoalt"
/obj/item/clothing/suit/storage/labcoat/mad
/obj/item/clothing/suit/storage/toggle/labcoat/mad
name = "The Mad's labcoat"
desc = "It makes you look capable of konking someone on the noggin and shooting them into space."
icon_state = "labgreen_open"
item_state = "labgreen"
icon_open = "labgreen_open"
icon_closed = "labgreen"
/obj/item/clothing/suit/storage/labcoat/genetics
/obj/item/clothing/suit/storage/toggle/labcoat/genetics
name = "Geneticist labcoat"
desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder."
icon_state = "labcoat_gen_open"
icon_open = "labcoat_gen_open"
icon_closed = "labcoat_gen"
/obj/item/clothing/suit/storage/labcoat/chemist
/obj/item/clothing/suit/storage/toggle/labcoat/chemist
name = "Chemist labcoat"
desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder."
icon_state = "labcoat_chem_open"
icon_open = "labcoat_chem_open"
icon_closed = "labcoat_chem"
/obj/item/clothing/suit/storage/labcoat/virologist
/obj/item/clothing/suit/storage/toggle/labcoat/virologist
name = "Virologist labcoat"
desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder."
icon_state = "labcoat_vir_open"
icon_open = "labcoat_vir_open"
icon_closed = "labcoat_vir"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 0)
/obj/item/clothing/suit/storage/labcoat/science
/obj/item/clothing/suit/storage/toggle/labcoat/science
name = "Scientist labcoat"
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
icon_state = "labcoat_tox_open"
icon_open = "labcoat_tox_open"
icon_closed = "labcoat_tox"
+6 -46
View File
@@ -199,28 +199,6 @@
item_state = "ianshirt"
body_parts_covered = UPPER_TORSO|ARMS
//Blue suit jacket toggle
/obj/item/clothing/suit/suit/verb/toggle()
set name = "Toggle Jacket Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if(src.icon_state == "suitjacket_blue_open")
src.icon_state = "suitjacket_blue"
src.item_state = "suitjacket_blue"
usr << "You button up the suit jacket."
else if(src.icon_state == "suitjacket_blue")
src.icon_state = "suitjacket_blue_open"
src.item_state = "suitjacket_blue_open"
usr << "You unbutton the suit jacket."
else
usr << "You button-up some imaginary buttons on your [src]."
return
update_clothing_icon()
//pyjamas
//originally intended to be pinstripes >.>
@@ -401,38 +379,20 @@
icon_state = "leather_jacket_nt"
//This one has buttons for some reason
/obj/item/clothing/suit/storage/brown_jacket
/obj/item/clothing/suit/storage/toggle/brown_jacket
name = "leather jacket"
desc = "A brown leather coat."
icon_state = "brown_jacket"
item_state = "brown_jacket"
var/open_state = "brown_jacket_open"
icon_open = "brown_jacket_open"
icon_closed = "brown_jacket"
body_parts_covered = UPPER_TORSO|ARMS
/obj/item/clothing/suit/storage/brown_jacket/nanotrasen
/obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen
desc = "A brown leather coat. The letters NT are proudly displayed on the back."
icon_state = "brown_jacket_nt"
open_state = "brown_jacket_nt_open"
/obj/item/clothing/suit/storage/brown_jacket/verb/toggle()
set name = "Toggle Jacket Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
//The inhand sprite (the mob sprite that appears when holding the item in your hand)
//is unchanged, so update only icon_state, not item_state.
if(icon_state == open_state)
usr << "You button up the jacket."
src.icon_state = initial(icon_state)
else if(icon_state == initial(icon_state))
usr << "You unbutton the jacket."
src.icon_state = open_state
update_clothing_icon() //so our overlays update
icon_open = "brown_jacket_nt_open"
icon_closed = "brown_jacket_nt"
/obj/item/clothing/suit/hoodie
name = "grey hoodie"
+23 -1
View File
@@ -26,4 +26,26 @@
/obj/item/clothing/suit/storage/hear_talk(mob/M, var/msg)
pockets.hear_talk(M, msg)
..()
..()
//Jackets with buttons, used for labcoats, IA jackets, First Responder jackets, and brown jackets.
/obj/item/clothing/suit/storage/toggle
var/icon_open
var/icon_closed
verb/toggle()
set name = "Toggle Coat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if(icon_state == icon_open) //Will check whether icon state is currently set to the "open" or "closed" state and switch it around with a message to the user
icon_state = icon_closed
usr << "You button up the coat."
else if(icon_state == icon_closed)
icon_state = icon_open
usr << "You unbutton the coat."
else //in case some goofy admin switches icon states around without switching the icon_open or icon_closed
usr << "You attempt to button-up the velcro on your [src], before promptly realising how silly you are."
return
update_clothing_icon() //so our overlays update
+3 -3
View File
@@ -120,7 +120,7 @@
New()
..()
var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/space/space_ninja,
/obj/item/clothing/suit/golem, /obj/item/clothing/suit/suit, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice,
/obj/item/clothing/suit/golem, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice,
/obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits.
for(var/U in typesof(/obj/item/clothing/suit)-blocked)
var/obj/item/clothing/suit/V = new U
@@ -257,7 +257,7 @@
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
@@ -464,7 +464,7 @@
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
+18 -1
View File
@@ -358,7 +358,7 @@
/obj/item/weapon/reagent_containers/glass/beaker/large/fluff/nashida_bishara_1 //rukral:Nashida Bisha'ra
name = "Nashida's Etched Beaker"
desc = "The message: 'Please do not be removing this beaker from the chemistry lab. If lost, return to Nashida Bisha'ra' can be seen etched into the side of this 100 unit beaker."
desc = "The message: 'Please do not be removing this beaker from the chemistry lab. If lost, return to Nashida Bisha'ra' can be seen etched into the side of this large beaker."
icon = 'icons/obj/chemical.dmi'
icon_state = "beakerlarge"
matter = list("glass" = 5000)
@@ -865,6 +865,15 @@
icon_state = "mitlabcoat"
item_state = "mitlabcoat"
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/epsilon //Devildabeast: Looping Song
name = "e UMi labcoat"
desc = "A suit that protects against minor chemical spills. Has a black stripe on the shoulder. The abbreviation \"e UMi\" is written on the back in bold text."
icon = 'icons/obj/custom_items.dmi'
icon_state = "labcoat_black_open"
icon_open = "labcoat_black_open"
icon_closed = "labcoat_black"
item_state = "labcoat_black"
/obj/item/clothing/suit/storage/det_suit/fluff/leatherjack //atomicdog92: Seth Sealis
name = "leather jacket"
desc = "A black leather coat, popular amongst punks, greasers, and other galactic scum."
@@ -1266,6 +1275,14 @@
icon_state = "digiboots"
species_restricted = null
/obj/item/clothing/shoes/jackboots/fluff/harmony_singh_1 //Bromuzl: Harmony Singh
name = "Springjacks"
desc = "A pair of highly modified jackboots in medical white, with some type of spring assembly on the ankle and heels, painted orange."
icon = 'icons/obj/custom_items.dmi'
icon_state = "springjacks"
item_state = "springjacks"
slowdown = SHOES_SLOWDOWN+1 //Slowing down because of her injured foot, these are for ease of pain so she can get off painkillers.
siemens_coefficient = 0.7 //copied from Jackboots under code/modules/clothing/shoes/miscellaneous.dm
//////////// Sets ////////////
-1
View File
@@ -1,6 +1,5 @@
/datum/event/economic_event
name = "Economic event"
endWhen = 50 //this will be set randomly, later
announceWhen = 15
var/event_type = 0
-2
View File
@@ -1,6 +1,5 @@
/datum/event/mundane_news
name = "Mundande news"
endWhen = 10
/datum/event/mundane_news/announce()
@@ -126,7 +125,6 @@
news_network.SubmitArticle(body, author, channel, null, 1)
/datum/event/trivial_news
name = "Trivial news"
endWhen = 10
/datum/event/trivial_news/announce()
-2
View File
@@ -1,9 +1,7 @@
/var/global/sent_aliens_to_station = 0
/datum/event/alien_infestation
name = "Alien Infestation"
announceWhen = 400
oneShot = 1
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
-1
View File
@@ -1,5 +1,4 @@
/datum/event/blob
name = "Blob"
announceWhen = 12
endWhen = 120
-5
View File
@@ -1,9 +1,4 @@
//Cortical borer spawn event - care of RobRichards1997 with minor editing by Zuhayr.
/datum/event/borer_infestation
name = "Borer Infestation"
oneShot = 1
/datum/event/borer_infestation
announceWhen = 400
@@ -1,8 +1,6 @@
/datum/event/brand_intelligence
name = "Brand Intelligence"
announceWhen = 21
endWhen = 1000 //Ends when all vending machines are subverted anyway.
oneShot = 1
var/list/obj/machinery/vending/vendingMachines = list()
var/list/obj/machinery/vending/infectedVendingMachines = list()
-2
View File
@@ -1,7 +1,5 @@
/datum/event/carp_migration
name = "Carp Migration"
announceWhen = 50
oneShot = 1
endWhen = 900
var/list/spawned_carp = list()
@@ -1,6 +1,3 @@
/datum/event/communications_blackout
name = "Communications Blackout"
/datum/event/communications_blackout/announce()
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v¬-BZZZT", \
-2
View File
@@ -1,7 +1,5 @@
/datum/event/disease_outbreak
name = "Disease Outbreak"
announceWhen = 15
oneShot = 1
/datum/event/disease_outbreak/announce()
-1
View File
@@ -1,5 +1,4 @@
/datum/event/electrical_storm
name = "Electrical Storm"
var/lightsoutAmount = 1
var/lightsoutRange = 25
+26 -13
View File
@@ -1,29 +1,37 @@
/datum/event_meta
var/name = ""
var/weight = 1
var/min_weight = 1
var/max_weight = 1
var/severity = 0
var/has_fired = 0
var/name = ""
var/enabled = 1 // Whether or not the event is available for random selection at all
var/weight = 0 // The base weight of this event. A zero means it may never fire, but see get_weight()
var/min_weight = 0 // The minimum weight that this event will have. Only used if non-zero.
var/max_weight = 0 // The maximum weight that this event will have. Only use if non-zero.
var/severity = 0 // The current severity of this event
var/one_shot = 0 //If true, then the event will not be re-added to the list of available events
var/list/role_weights = list()
var/datum/event/event_type
/datum/event_meta/New(var/event_severity, var/event_name, var/datum/event/type, var/event_weight, var/list/job_weights, var/min_event_weight, var/max_event_weight)
/datum/event_meta/New(var/event_severity, var/event_name, var/datum/event/type, var/event_weight, var/list/job_weights, var/is_one_shot = 0, var/min_event_weight = 0, var/max_event_weight = 0)
name = event_name
severity = event_severity
event_type = type
one_shot = is_one_shot
weight = event_weight
min_weight = min_event_weight
max_weight = max_event_weight
if(job_weights)
role_weights = job_weights
/datum/event_meta/proc/get_weight(var/list/active_with_role)
if(!enabled)
return 0
var/job_weight = 0
for(var/role in role_weights)
job_weight = active_with_role[role] * role_weights[role]
if(role in active_with_role)
job_weight += active_with_role[role] * role_weights[role]
var/total_weight = weight + job_weight
// Only min/max the weight if the values are set
// Only min/max the weight if the values are non-zero
if(min_weight && total_weight < min_weight) total_weight = min_weight
if(max_weight && total_weight > max_weight) total_weight = max_weight
@@ -40,19 +48,18 @@
return 0
/datum/event //NOTE: Times are measured in master controller ticks!
var/name = ""//Name of the event
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end.
var/oneShot = 0 //If true, then the event removes itself from the list of potential events on creation.
var/severity = 0 //Severity. Lower means less severe, higher means more severe. Does not have to be supported. Is set on New().
var/activeFor = 0 //How long the event has existed. You don't need to change this.
var/isRunning = 1 //If this event is currently running. You should not change this.
var/startedAt = 0 //When this event started.
var/endedAt = 0 //When this event ended.
var/datum/event_meta/event_meta = null
/datum/event/nothing
name = "Nothing"
//Called first before processing.
//Allows you to setup your event, such as randomly
@@ -89,6 +96,9 @@
/datum/event/proc/end()
return
//Returns the latest point of event processing.
/datum/event/proc/lastProcessAt()
return max(startWhen, max(announceWhen, endWhen))
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
@@ -108,7 +118,7 @@
end()
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
if(activeFor >= lastProcessAt())
kill()
activeFor++
@@ -120,6 +130,7 @@
isRunning = 0
end()
endedAt = world.time
event_manager.active_events -= src
event_manager.event_complete(src)
@@ -132,5 +143,7 @@
if(severity < EVENT_LEVEL_MUNDANE) severity = EVENT_LEVEL_MUNDANE
if(severity > EVENT_LEVEL_MAJOR) severity = EVENT_LEVEL_MAJOR
startedAt = world.time
setup()
..()
+179
View File
@@ -0,0 +1,179 @@
#define ASSIGNMENT_ANY "Any"
#define ASSIGNMENT_AI "AI"
#define ASSIGNMENT_CYBORG "Cyborg"
#define ASSIGNMENT_ENGINEER "Engineer"
#define ASSIGNMENT_GARDENER "Gardener"
#define ASSIGNMENT_JANITOR "Janitor"
#define ASSIGNMENT_MEDICAL "Medical"
#define ASSIGNMENT_SCIENTIST "Scientist"
#define ASSIGNMENT_SECURITY "Security"
var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major")
/datum/event_container
var/severity = -1
var/delayed = 0
var/delay_modifier = 1
var/next_event_time = 0
var/list/available_events
var/list/last_event_time = list()
var/datum/event_meta/next_event = null
var/last_world_time = 0
/datum/event_container/proc/process()
if(!next_event_time)
set_event_delay()
if(delayed)
next_event_time += (world.time - last_world_time)
else if(world.time > next_event_time)
start_event()
last_world_time = world.time
/datum/event_container/proc/start_event()
if(!next_event) // If non-one has explicitly set an event, randomly pick one
next_event = acquire_event()
// Has an event been acquired?
if(next_event)
// Set when the event of this type was last fired, and prepare the next event start
last_event_time[next_event] = world.time
set_event_delay()
next_event.enabled = !next_event.one_shot // This event will no longer be available in the random rotation if one shot
new next_event.event_type(next_event) // Events are added and removed from the processing queue in their New/kill procs
log_debug("Starting event '[next_event.name]' of severity [severity_to_string[severity]].")
next_event = null // When set to null, a random event will be selected next time
else
// If not, wait for one minute, instead of one tick, before checking again.
next_event_time += (60 * 10)
/datum/event_container/proc/acquire_event()
if(available_events.len == 0)
return
var/active_with_role = number_active_with_role()
var/list/possible_events = list()
for(var/datum/event_meta/EM in available_events)
var/event_weight = EM.get_weight(active_with_role)
if(EM.enabled && event_weight)
possible_events[EM] = event_weight
for(var/event_meta in last_event_time) if(possible_events[event_meta])
var/time_passed = world.time - event_last_fired[event_meta]
var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300)
var/new_weight = max(possible_events[event_meta] - weight_modifier, 0)
if(new_weight)
possible_events[event_meta] = new_weight
else
possible_events -= event_meta
if(possible_events.len == 0)
return null
// Select an event and remove it from the pool of available events
var/picked_event = pickweight(possible_events)
available_events -= picked_event
return picked_event
/datum/event_container/proc/set_event_delay()
// If the next event time has not yet been set and we have a custom first time start
if(next_event_time == 0 && config.event_first_run[severity])
var/lower = config.event_first_run[severity]["lower"]
var/upper = config.event_first_run[severity]["upper"]
var/event_delay = rand(lower, upper)
next_event_time = world.time + event_delay
// Otherwise, follow the standard setup process
else
var/playercount_modifier = 1
switch(player_list.len)
if(0 to 10)
playercount_modifier = 1.2
if(11 to 15)
playercount_modifier = 1.1
if(16 to 25)
playercount_modifier = 1
if(26 to 35)
playercount_modifier = 0.9
if(36 to 100000)
playercount_modifier = 0.8
playercount_modifier = playercount_modifier * delay_modifier
var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier
next_event_time = world.time + event_delay
log_debug("Next event of severity [severity_to_string[severity]] in [(next_event_time - world.time)/600] minutes.")
/datum/event_container/proc/SelectEvent()
var/datum/event_meta/EM = input("Select an event to queue up.", "Event Selection", null) as null|anything in available_events
if(!EM)
return
if(next_event)
available_events += next_event
available_events -= EM
next_event = EM
return EM
/datum/event_container/mundane
severity = EVENT_LEVEL_MUNDANE
available_events = list(
// Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
)
/datum/event_container/moderate
severity = EVENT_LEVEL_MODERATE
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 10),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 5, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_SECURITY = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space vines", /datum/event/spacevine, 10, list(ASSIGNMENT_ENGINEER = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 50, list(ASSIGNMENT_AI = 25, ASSIGNMENT_SECURITY = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 50)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 25, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 15, list(ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_JANITOR = 15)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 5, list(ASSIGNMENT_SECURITY = 5), 1),
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5,list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 25, ASSIGNMENT_CYBORG = 25, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SCIENTIST = 5)),
)
/datum/event_container/major
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 50),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 10), 1),
)
#undef ASSIGNMENT_ANY
#undef ASSIGNMENT_AI
#undef ASSIGNMENT_CYBORG
#undef ASSIGNMENT_ENGINEER
#undef ASSIGNMENT_GARDENER
#undef ASSIGNMENT_JANITOR
#undef ASSIGNMENT_MEDICAL
#undef ASSIGNMENT_SCIENTIST
#undef ASSIGNMENT_SECURITY
+222 -200
View File
@@ -1,72 +1,24 @@
#define ASSIGNMENT_ANY "Any"
#define ASSIGNMENT_AI "AI"
#define ASSIGNMENT_CYBORG "Cyborg"
#define ASSIGNMENT_ENGINEER "Engineer"
#define ASSIGNMENT_GARDENER "Gardener"
#define ASSIGNMENT_JANITOR "Janitor"
#define ASSIGNMENT_MEDICAL "Medical"
#define ASSIGNMENT_SCIENTIST "Scientist"
#define ASSIGNMENT_SECURITY "Security"
var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major")
/datum/event_manager
var/list/available_events = list(
EVENT_LEVEL_MUNDANE = list(
// Severity level, event name, even type, base weight, role weights, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 25, 200),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 5, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 25, 200),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wall root", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence", /datum/event/brand_intelligence, 20, list(ASSIGNMENT_JANITOR = 25)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation", /datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
),
EVENT_LEVEL_MODERATE = list(
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 10),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp Infestation", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 5, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_SECURITY = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space vines", /datum/event/spacevine, 10, list(ASSIGNMENT_ENGINEER = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 50, list(ASSIGNMENT_AI = 25, ASSIGNMENT_SECURITY = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 25, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 15, list(ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_JANITOR = 15)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation",/datum/event/spider_infestation, 5, list(ASSIGNMENT_SECURITY = 5)),
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5,list(ASSIGNMENT_SECURITY = 1), max_event_weight = 5),
new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), max_event_weight = 5),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 25, ASSIGNMENT_CYBORG = 25, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SCIENTIST = 5)),
),
EVENT_LEVEL_MAJOR = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 100),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 10)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 10)),
)
)
var/window_x = 370
var/window_y = 530
var/window_x = 700
var/window_y = 600
var/report_at_round_end = 0
var/table_options = " align='center'"
var/row_options1 = " width='85px'"
var/row_options2 = " width='260px'"
var/row_options3 = " width='150px'"
var/datum/event_container/selected_event_container = null
var/list/datum/event/active_events = list()
var/list/datum/event/finished_events = list()
var/list/datum/event/allEvents
var/list/datum/event_container/event_containers = list(
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
EVENT_LEVEL_MAJOR = new/datum/event_container/major
)
var/list/last_event_time = list()
var/list/next_event = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = null)
var/list/next_event_time = list(EVENT_LEVEL_MUNDANE = 0, EVENT_LEVEL_MODERATE = 0, EVENT_LEVEL_MAJOR = 0)
var/list/delay_modifier = list(EVENT_LEVEL_MUNDANE = 1, EVENT_LEVEL_MODERATE = 1, EVENT_LEVEL_MAJOR = 1)
var/datum/event_meta/new_event = new
/datum/event_manager/New()
allEvents = typesof(/datum/event) - /datum/event
@@ -76,99 +28,22 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
E.process()
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
// Is it time to fire a new event of this severity level?
if(world.timeofday > next_event_time[i])
process_event_start(i)
/datum/event_manager/proc/process_event_start(var/severity)
var/event = next_event[severity]
if(event)
start_event(event)
// Attempt to select a new event
next_event[severity] = acquire_event(available_events[severity])
if(next_event[severity]) // If we got an event, set the next delay proper
set_event_delay(severity)
else // Otherwise, wait for one minute (rather than next process tick) before checking again
next_event_time[severity] += (60 * 10)
/datum/event_manager/proc/start_event(var/datum/event_meta/EM)
// Set when the event of this type was last fired
last_event_time[EM] = world.timeofday
log_debug("Starting event of severity [EM.severity].")
new EM.event_type(EM) // Events are added and removed from the processing queue in New/Del
/datum/event_manager/proc/acquire_event(var/list/events)
if(events.len == 0)
return
var/active_with_role = number_active_with_role()
var/list/possible_events = list()
for(var/datum/event_meta/EM in events)
var/event_weight = EM.get_weight(active_with_role)
if(event_weight)
possible_events[EM] = event_weight
for(var/event_meta in last_event_time) if(possible_events[event_meta])
var/time_passed = world.timeofday - event_last_fired[event_meta]
var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300)
var/new_weight = max(possible_events[event_meta] - weight_modifier, 0)
if(new_weight)
possible_events[event_meta] = new_weight
else
possible_events -= event_meta
if(possible_events.len == 0)
return null
// Select an event and remove it from the pool of available events
var/picked_event = pickweight(possible_events)
events -= picked_event
return picked_event
/datum/event_manager/proc/set_event_delay(var/severity)
// If the next event time has not yet been set and we have a custom first time start
if(next_event_time[severity] == 0 && config.event_first_run[severity])
var/lower = config.event_first_run[severity]["lower"]
var/upper = config.event_first_run[severity]["upper"]
var/event_delay = rand(lower, upper)
next_event_time[severity] = world.timeofday + event_delay
// Otherwise, follow the standard setup process
else
var/playercount_modifier = 1
switch(player_list.len)
if(0 to 10)
playercount_modifier = 1.2
if(11 to 15)
playercount_modifier = 1.1
if(16 to 25)
playercount_modifier = 1
if(26 to 35)
playercount_modifier = 0.9
if(36 to 100000)
playercount_modifier = 0.8
playercount_modifier = playercount_modifier * delay_modifier[severity]
var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier
next_event_time[severity] = world.timeofday + event_delay
log_debug("Next event of severity [severity] in [(next_event_time[severity] - world.timeofday)/600] minutes.")
var/list/datum/event_container/EC = event_containers[i]
EC.process()
/datum/event_manager/proc/event_complete(var/datum/event/E)
if(!E.event_meta) // datum/event is used here and there for random reasons
if(!E.event_meta) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
log_debug("Event of '[E.type]' with missing meta-data has completed.")
return
finished_events += E
// Add the event back to the list of available events, unless it's a oneShot
if(!E.oneShot)
var/list/datum/event_meta/AE = available_events[E.event_meta.severity]
AE.Add(E.event_meta)
log_debug("Event '[E.name]' has completed.")
// Add the event back to the list of available events
var/datum/event_container/EC = event_containers[E.severity]
var/datum/event_meta/EM = E.event_meta
EC.available_events += EM
log_debug("Event '[EM.name]' has completed at [worldtime2text()].")
/datum/event_manager/proc/Interact(var/mob/living/user)
@@ -178,40 +53,130 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
popup.set_content(html)
popup.open()
/datum/event_manager/proc/RoundEnd()
if(!report_at_round_end)
return
world << "<br><br><br><font size=3><b>Random Events This Round:</b></font>"
for(var/datum/event/E in active_events|finished_events)
var/datum/event_meta/EM = E.event_meta
if(EM.name == "Nothing")
continue
var/message = "'[EM.name]' began at [worldtime2text(E.startedAt)] "
if(E.isRunning)
message += "and is still running."
else
if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes
message += "and ended at [worldtime2text(E.endedAt)]."
else
message += "and ran to completion."
world << message
/datum/event_manager/proc/GetInteractWindow()
var html = "<A align='right' href='?src=\ref[src];refresh=1'>Refresh</A><br>"
var/html = "<A align='right' href='?src=\ref[src];refresh=1'>Refresh</A>"
html += "<div class='block'>"
html += "<h2>Event Start</h2>"
html += "<table[table_options]>"
html += "<tr><td>Severity</td><td>Until start</td><td>Adjust start</td></tr>"
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
var/event_time = max(0, next_event_time[severity] - world.timeofday)
html += "<tr>"
html += "<td[row_options1]>[severity_to_string[severity]]</font></td>"
html += "<td[row_options1]>[event_time / 600]</td>"
html += "<td[row_options2]>"
html += "<A align='right' href='?src=\ref[src];dec_timer=2;severity=[severity]'>--</A>"
html += "<A align='right' href='?src=\ref[src];dec_timer=1;severity=[severity]'>-</A>"
html += "<A align='right' href='?src=\ref[src];inc_timer=1;severity=[severity]'>+</A>"
html += "<A align='right' href='?src=\ref[src];inc_timer=2;severity=[severity]'>++</A>"
html += "</td>"
html += "</tr>"
html += "</table>"
html += "</div>"
if(selected_event_container)
var/event_time = max(0, selected_event_container.next_event_time - world.time)
html += "<A align='right' href='?src=\ref[src];back=1'>Back</A><br>"
html += "Time till start: [round(event_time / 600, 0.1)]<br>"
html += "<div class='block'>"
html += "<h2>Available [severity_to_string[selected_event_container.severity]] Events (queued & running events will not be displayed)</h2>"
html += "<table[table_options]>"
html += "<tr><td[row_options2]>Name </td><td>Weight </td><td>MinWeight </td><td>MaxWeight </td><td>OneShot </td><td>Enabled </td><td><span class='alert'>CurrWeight </span></td><td>Remove</td></tr>"
for(var/datum/event_meta/EM in selected_event_container.available_events)
html += "<tr>"
html += "<td>[EM.name]</td>"
html += "<td><A align='right' href='?src=\ref[src];set_weight=\ref[EM]'>[EM.weight]</A></td>"
html += "<td>[EM.min_weight]</td>"
html += "<td>[EM.max_weight]</td>"
html += "<td><A align='right' href='?src=\ref[src];toggle_oneshot=\ref[EM]'>[EM.one_shot]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];toggle_enabled=\ref[EM]'>[EM.enabled]</A></td>"
html += "<td><span class='alert'>[EM.get_weight()]</span></td>"
html += "<td><A align='right' href='?src=\ref[src];remove=\ref[EM];EC=\ref[selected_event_container]'>Remove</A></td>"
html += "</tr>"
html += "</table>"
html += "</div>"
html += "<div class='block'>"
html += "<h2>Next Event</h2>"
html += "<table[table_options]>"
html += "<tr><td>Severity</td><td>Name</td></tr>"
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
var/datum/event_meta/EM = next_event[severity]
html += "<div class='block'>"
html += "<h2>Add Event</h2>"
html += "<table[table_options]>"
html += "<tr><td[row_options2]>Name</td><td[row_options2]>Type</td><td[row_options1]>Weight</td><td[row_options1]>OneShot</td></tr>"
html += "<tr>"
html += "<td[row_options1]>[severity_to_string[severity]]</font></td>"
html += "<td[row_options2]><A align='right' href='?src=\ref[src];select_event=1;severity=[severity]'>[EM ? EM.name : "Nothing"]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];set_name=\ref[new_event]'>[new_event.name ? new_event.name : "Enter Event"]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];set_type=\ref[new_event]'>[new_event.event_type ? new_event.event_type : "Select Type"]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];set_weight=\ref[new_event]'>[new_event.weight ? new_event.weight : 0]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];set_oneshot=\ref[new_event]'>[new_event.one_shot]</A></td>"
html += "</tr>"
html += "</table>"
html += "</div>"
html += "</table>"
html += "<A align='right' href='?src=\ref[src];add=\ref[selected_event_container]'>Add</A><br>"
html += "</div>"
else
html += "<A align='right' href='?src=\ref[src];toggle_report=1'>Round End Report: [report_at_round_end ? "On": "Off"]</A><br>"
html += "<div class='block'>"
html += "<h2>Event Start</h2>"
html += "<table[table_options]>"
html += "<tr><td[row_options1]>Severity</td><td[row_options1]>Starts At</td><td[row_options1]>Starts In</td><td[row_options3]>Adjust Start</td><td[row_options1]>Pause</td><td[row_options1]>Interval Mod</td></tr>"
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
var/datum/event_container/EC = event_containers[severity]
var/next_event_at = max(0, EC.next_event_time - world.time)
html += "<tr>"
html += "<td>[severity_to_string[severity]]</td>"
html += "<td>[worldtime2text(max(EC.next_event_time, world.time))]</td>"
html += "<td>[round(next_event_at / 600, 0.1)]</td>"
html += "<td>"
html += "<A align='right' href='?src=\ref[src];dec_timer=2;event=\ref[EC]'>--</A>"
html += "<A align='right' href='?src=\ref[src];dec_timer=1;event=\ref[EC]'>-</A>"
html += "<A align='right' href='?src=\ref[src];inc_timer=1;event=\ref[EC]'>+</A>"
html += "<A align='right' href='?src=\ref[src];inc_timer=2;event=\ref[EC]'>++</A>"
html += "</td>"
html += "<td>"
html += "<A align='right' href='?src=\ref[src];pause=\ref[EC]'>[EC.delayed ? "Resume" : "Pause"]</A>"
html += "</td>"
html += "<td>"
html += "<A align='right' href='?src=\ref[src];interval=\ref[EC]'>[EC.delay_modifier]</A>"
html += "</td>"
html += "</tr>"
html += "</table>"
html += "</div>"
html += "<div class='block'>"
html += "<h2>Next Event</h2>"
html += "<table[table_options]>"
html += "<tr><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options3]>Event Rotation</td><td>Clear</td></tr>"
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
var/datum/event_container/EC = event_containers[severity]
var/datum/event_meta/EM = EC.next_event
html += "<tr>"
html += "<td>[severity_to_string[severity]]</td>"
html += "<td><A align='right' href='?src=\ref[src];select_event=\ref[EC]'>[EM ? EM.name : "Random"]</A></td>"
html += "<td><A align='right' href='?src=\ref[src];view_events=\ref[EC]'>View</A></td>"
html += "<td><A align='right' href='?src=\ref[src];clear=\ref[EC]'>Clear</A></td>"
html += "</tr>"
html += "</table>"
html += "</div>"
html += "<div class='block'>"
html += "<h2>Running Events</h2>"
html += "Estimated times, affected by master controller delays."
html += "<table[table_options]>"
html += "<tr><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options1]>Ends At</td><td[row_options1]>Ends In</td><td[row_options3]>Stop</td></tr>"
for(var/datum/event/E in active_events)
if(!E.event_meta)
continue
var/datum/event_meta/EM = E.event_meta
var/ends_at = E.startedAt + (E.lastProcessAt() * master_controller.minimum_ticks) // A best estimate
var/ends_in = max(0, round((ends_at - world.time) / 600, 0.1))
html += "<tr>"
html += "<td>[severity_to_string[EM.severity]]</td>"
html += "<td>[EM.name]</td>"
html += "<td>[worldtime2text(ends_at)]</td>"
html += "<td>[ends_in]</td>"
html += "<td><A align='right' href='?src=\ref[src];stop=\ref[E]'>Stop</A></td>"
html += "</tr>"
html += "</table>"
html += "</div>"
return html
@@ -219,28 +184,95 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
if(..())
return
var/severity = text2num(href_list["severity"])
if(href_list["dec_timer"])
next_event_time[severity] -= (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
if(href_list["toggle_report"])
report_at_round_end = !report_at_round_end
admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
else if(href_list["dec_timer"])
var/datum/event_container/EC = locate(href_list["event"])
var/decrease = (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
EC.next_event_time -= decrease
admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
else if(href_list["inc_timer"])
next_event_time[severity] += (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
var/datum/event_container/EC = locate(href_list["event"])
var/increase = (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
EC.next_event_time += increase
admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
else if(href_list["select_event"])
SelectEvent(severity)
var/datum/event_container/EC = locate(href_list["select_event"])
var/datum/event_meta/EM = EC.SelectEvent()
if(EM)
admin_log_and_message_admins("has queued the [severity_to_string[EC.severity]] event '[EM.name]'.")
else if(href_list["pause"])
var/datum/event_container/EC = locate(href_list["pause"])
EC.delayed = !EC.delayed
admin_log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.")
else if(href_list["interval"])
var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null
if(delay && delay > 0)
var/datum/event_container/EC = locate(href_list["interval"])
EC.delay_modifier = delay
admin_log_and_message_admins("has set the interval modifier for [severity_to_string[EC.severity]] events to [EC.delay_modifier].")
else if(href_list["stop"])
if(alert("Stopping an event may have unintended side-effects. Continue?","Stopping Event!","Yes","No") != "Yes")
return
var/datum/event/E = locate(href_list["stop"])
var/datum/event_meta/EM = E.event_meta
admin_log_and_message_admins("has stopped the [severity_to_string[EM.severity]] event '[EM.name]'.")
E.kill()
else if(href_list["view_events"])
selected_event_container = locate(href_list["view_events"])
else if(href_list["back"])
selected_event_container = null
else if(href_list["set_name"])
var/name = input("Enter event name.", "Set Name") as text|null
if(name)
var/datum/event_meta/EM = locate(href_list["set_name"])
EM.name = name
else if(href_list["set_type"])
var/type = input("Select event type.", "Select") as null|anything in allEvents
if(type)
var/datum/event_meta/EM = locate(href_list["set_type"])
EM.event_type = type
else if(href_list["set_weight"])
var/weight = input("Enter weight. A higher value means higher chance for the event of being selected.", "Set Weight") as num|null
if(weight && weight > 0)
var/datum/event_meta/EM = locate(href_list["set_weight"])
EM.weight = weight
if(EM != new_event)
admin_log_and_message_admins("has changed the weight of the [severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
else if(href_list["toggle_oneshot"])
var/datum/event_meta/EM = locate(href_list["toggle_oneshot"])
EM.one_shot = !EM.one_shot
if(EM != new_event)
admin_log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["toggle_enabled"])
var/datum/event_meta/EM = locate(href_list["toggle_enabled"])
EM.enabled = !EM.enabled
admin_log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["remove"])
if(alert("This will remove the event from rotation. Continue?","Removing Event!","Yes","No") != "Yes")
return
var/datum/event_meta/EM = locate(href_list["remove"])
var/datum/event_container/EC = locate(href_list["EC"])
EC.available_events -= EM
admin_log_and_message_admins("has removed the [severity_to_string[EM.severity]] event '[EM.name]'.")
else if(href_list["add"])
if(!new_event.name || !new_event.event_type)
return
if(alert("This will add a new event to the rotation. Continue?","Add Event!","Yes","No") != "Yes")
return
selected_event_container.available_events += new_event
admin_log_and_message_admins("has added \a [severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
new_event = new
else if(href_list["clear"])
var/datum/event_container/EC = locate(href_list["clear"])
if(EC.next_event)
admin_log_and_message_admins("has unqueued the [severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
EC.next_event = null
Interact(usr)
/datum/event_manager/proc/SelectEvent(var/severity)
var/datum/event_meta/EM = input("Select an event to queue up.", "Event Selection", null) as null|anything in available_events[severity]
if(!EM)
return
if(next_event[severity])
available_events[severity] += next_event[severity]
available_events[severity] -= EM
next_event[severity] = EM
/proc/debugStartEvent(var/severity)
event_manager.start_event(severity)
/client/proc/forceEvent(var/type in event_manager.allEvents)
set name = "Trigger Event (Debug Only)"
set category = "Debug"
@@ -259,13 +291,3 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
event_manager.Interact(usr)
feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
#undef ASSIGNMENT_ANY
#undef ASSIGNMENT_AI
#undef ASSIGNMENT_CYBORG
#undef ASSIGNMENT_ENGINEER
#undef ASSIGNMENT_GARDENER
#undef ASSIGNMENT_JANITOR
#undef ASSIGNMENT_MEDICAL
#undef ASSIGNMENT_SCIENTIST
#undef ASSIGNMENT_SECURITY
-1
View File
@@ -1,5 +1,4 @@
/datum/event/grid_check //NOTE: Times are measured in master controller ticks!
name = "Grid Check"
announceWhen = 5
/datum/event/grid_check/setup()
-1
View File
@@ -14,7 +14,6 @@
#define VERM_SPIDERS 2
/datum/event/infestation
name = "Vermin Infestation"
announceWhen = 10
endWhen = 11
var/location
-1
View File
@@ -1,7 +1,6 @@
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
/datum/event/ionstorm
name = "Ion Storm"
var/botEmagChance = 0.5
var/list/players = list()
-2
View File
@@ -2,7 +2,6 @@
//meteor storms are much heavier
/datum/event/meteor_wave
name = "Meteor Wave"
startWhen = 6
endWhen = 33
@@ -21,7 +20,6 @@
//
/datum/event/meteor_shower
name = "Meteor Shower"
startWhen = 5
endWhen = 7
var/next_meteor = 6
-1
View File
@@ -1,7 +1,6 @@
/var/global/account_hack_attempted = 0
/datum/event/money_hacker
name = "Money Hacker"
var/datum/money_account/affected_account
endWhen = 100
var/end_time
-1
View File
@@ -1,5 +1,4 @@
/datum/event/money_lotto
name = "Money Lotto"
var/winner_name = "John Smith"
var/winner_sum = 0
var/deposit_success = 0
-1
View File
@@ -1,5 +1,4 @@
/datum/event/pda_spam
name = "PDA Spam"
endWhen = 36000
var/last_spam_time = 0
var/obj/machinery/message_server/useMS
-2
View File
@@ -1,7 +1,5 @@
/datum/event/prison_break
name = "Prison Break"
announceWhen = 50
oneShot = 1
var/releaseWhen = 25
var/list/area/prisonAreas = list()
-2
View File
@@ -1,11 +1,9 @@
/datum/event/radiation_storm
name = "Radiation Storm"
var/const/enterBelt = 60
var/const/leaveBelt = 170
var/const/revokeAccess = 230
endWhen = revokeAccess
oneShot = 1
var/postStartTicks
-2
View File
@@ -1,6 +1,4 @@
/datum/event/rogue_drone
name = "Rogue Drones"
startWhen = 10
endWhen = 1000
var/list/drones_list = list()
-4
View File
@@ -1,5 +1 @@
/datum/event/space_ninja
name = "Space Ninja"
/datum/event/space_ninja/setup()
space_ninja_arrival()
-4
View File
@@ -1,9 +1,5 @@
/var/global/spacevines_spawned = 0
/datum/event/spacevine
name = "Space Vines"
oneShot = 1
/datum/event/spacevine/start()
//biomass is basically just a resprited version of space vines
if(prob(50))
@@ -1,9 +1,7 @@
/var/global/sent_spiders_to_station = 0
/datum/event/spider_infestation
name = "Large Spider Infestation"
announceWhen = 400
oneShot = 1
var/spawncount = 1
@@ -1,6 +1,3 @@
/datum/event/spontaneous_appendicitis
name = "Communicatinos Blackout"
/datum/event/spontaneous_appendicitis/start()
for(var/mob/living/carbon/human/H in shuffle(living_mob_list)) if(H.client && H.stat != DEAD)
var/foundAlready = 0 //don't infect someone that already has the virus
-1
View File
@@ -1,5 +1,4 @@
datum/event/viral_infection/setup()
name = "Viral Outbreak"
announceWhen = rand(0, 3000)
endWhen = announceWhen + 1
-1
View File
@@ -1,5 +1,4 @@
datum/event/wallrot/setup()
name = "Wallroot"
announceWhen = rand(0, 300)
endWhen = announceWhen + 1
@@ -58,9 +58,6 @@
if(world.time > last_action + action_time)
finished_task()
/obj/machinery/botany/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/botany/attack_ai(mob/user as mob)
return attack_hand(user)
+1 -4
View File
@@ -41,6 +41,7 @@
if(/obj/item/weapon/twohanded/fireaxe) del src
if(/obj/item/weapon/hatchet) del src
if(/obj/item/weapon/melee/energy) del src
if(/obj/item/weapon/pickaxe/plasmacutter) del src
// Less effective weapons
if(/obj/item/weapon/wirecutters)
@@ -72,10 +73,6 @@
manual_unbuckle(user)
/obj/effect/plantsegment/attack_paw(mob/user as mob)
manual_unbuckle(user)
/obj/effect/plantsegment/proc/unbuckle()
if(buckled_mob)
if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
+284 -287
View File
@@ -1,325 +1,322 @@
dmm_suite
///////////////////////////////////////////////////////////////
//SS13 Optimized Map loader
//////////////////////////////////////////////////////////////
var/debug_file = file("maploader_debug.txt")
load_map(var/dmm_file as file, var/z_offset as num, var/y_offset as num, var/x_offset as num, var/load_speed = 0 as num)
if(!z_offset)
z_offset = world.maxz + 1
/**
* Construct the model map and control the loading process
*
* WORKING :
*
* 1) Makes an associative mapping of model_keys with model
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
* 2) Read the map line by line, parsing the result (using parse_grid)
*
*/
/dmm_suite/load_map(var/dmm_file as file, var/z_offset as num)
if(!z_offset)//what z_level we are creating the map on
z_offset = world.maxz+1
//Ensure values are sane.
else if(z_offset < 0)
z_offset = abs(z_offset)
else if(!isnum(z_offset))
z_offset = 0
var/quote = ascii2text(34)
var/tfile = file2text(dmm_file)//the map file we're creating
var/tfile_len = length(tfile)
var/lpos = 1 // the models definition index
if(x_offset < 0)
x_offset = abs(x_offset)
else if(!isnum(x_offset))
x_offset = 0
///////////////////////////////////////////////////////////////////////////////////////
//first let's map model keys (e.g "aa") to their contents (e.g /turf/space{variables})
///////////////////////////////////////////////////////////////////////////////////////
var/list/grid_models = list()
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))//the length of the model key (e.g "aa" or "aba")
if(y_offset < 0)
y_offset = abs(y_offset)
else if(!isnum(y_offset))
y_offset = 0
//proceed line by line
for(lpos=1; lpos<tfile_len; lpos=findtext(tfile,"\n",lpos,0)+1)
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
if(copytext(tline,1,2) != quote)//we reached the map "layout"
break
var/model_key = copytext(tline,2,2+key_len)
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
grid_models[model_key] = model_contents
sleep(-1)
debug_file << "Starting Map Load @ ([x_offset], [y_offset], [z_offset]), [load_speed] tiles per second."
///////////////////////////////////////////////////////////////////////////////////////
//now let's fill the map with turf and objects using the constructed model map
///////////////////////////////////////////////////////////////////////////////////////
//Handle slowed loading.
var/delay_chance = 0
if(load_speed > 0)
//Chance out of 100 every tenth of a second.
delay_chance = 1000 / load_speed
//position of the currently processed square
var/zcrd=-1
var/ycrd=0
var/xcrd=0
//String holding a quotation mark.
var/quote = ascii2text(34)
for(var/zpos=findtext(tfile,"\n(1,1,",lpos,0);zpos!=0;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)) //in case there's several maps to load
var/input_file = file2text(dmm_file)
var/input_file_len = length(input_file)
zcrd++
world.maxz = max(world.maxz, zcrd+z_offset)//create a new z_level if needed
//Stores the contents of each tile model in the map
var/list/grid_models = list()
//Length of the tile model code. e.g. "aaa" is 3 long.
var/key_len = length(copytext(input_file, 2 ,findtext(input_file, quote, 2)))
//The key of the default tile model. (In SS13 this is: "/turf/space,/area")
var/default_key
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1) //copy the whole map grid
var/z_depth = length(zgrid)
debug_file << " Building turf array."
//if exceeding the world max x or y, increase it
var/x_depth = length(copytext(zgrid,1,findtext(zgrid,"\n",2,0)))
if(world.maxx<x_depth)
world.maxx=x_depth
//Iterates through the mapfile to build the model tiles for the map.
for(var/line_position = 1; line_position < input_file_len; line_position = findtext(input_file,"\n", line_position) + 1)
var/next_line = copytext(input_file, line_position, findtext(input_file,"\n", line_position) - 1)
var/y_depth = z_depth / (x_depth+1)//x_depth + 1 because we're counting the '\n' characters in z_depth
if(world.maxy<y_depth)
world.maxy=y_depth
//If the first character in the line is not a quote, the model tiles are all defined.
if(copytext(next_line, 1, 2) != quote)
//then proceed it line by line, starting from top
ycrd = y_depth
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1)
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0))
//fill the current square using the model map
xcrd=0
for(var/mpos=1;mpos<=x_depth;mpos+=key_len)
xcrd++
var/model_key = copytext(grid_line,mpos,mpos+key_len)
parse_grid(grid_models[model_key],xcrd,ycrd,zcrd+z_offset)
//reached end of current map
if(gpos+x_depth+1>z_depth)
break
//Copy contents of the model into the grid_models list.
var/model_key = copytext(next_line, 2, findtext(input_file, quote, 2))
var/model_contents = copytext(next_line, findtext(next_line, "=" ) + 3)
if(!default_key && model_contents == "[world.turf],[world.area]")
default_key = model_key
grid_models[model_key] = model_contents
if(prob(delay_chance))
sleep(1)
//Co-ordinates of the tile being loaded.
var/z_coordinate = -1
var/y_coordinate = 0
var/x_coordinate = 0
//Store the
var/y_depth = 0
//Iterate through all z-levels to load the tiles.
for(var/z_position = findtext(input_file, "\n(1,1,"); TRUE; z_position = findtext(input_file, "\n(1,1,", z_position + 1))
//break when there are no more z-levels.
if(z_position == 0)
break
//Increment the z_coordinate and update the world's borders
z_coordinate++
world.maxz = max(world.maxz, z_coordinate + z_offset)
//Here we go!
y_coordinate = 0
y_depth = 0
var/z_level = copytext(input_file, \
findtext(input_file, quote + "\n", z_position) + 2,\
findtext(input_file, "\n" + quote, z_position) + 1)
//Iterate through each line, increasing the y_coordinate.
for(var/grid_position = 1; grid_position != 0; grid_position = findtext(z_level, "\n", grid_position) + 1)
//Grab this line of data.
var/grid_line = copytext(z_level, grid_position, findtext(z_level, "\n", grid_position))
//Compute the size of the z-levels y axis.
if(!y_depth)
y_depth = length(z_level) / (length(grid_line) + 1)
y_depth += y_offset
if(y_depth != round(y_depth, 1))
debug_file << " Warning: y_depth is not a round number"
//And update the worlds variables.
if(world.maxy < y_depth)
world.maxy = y_depth
//The top of the map is the highest "y" co-ordinate, so we start there and iterate downwards
if(!y_coordinate)
y_coordinate = y_depth + 1
//Decrement and load this line of the map.
y_coordinate--
x_coordinate = x_offset
//Iterate through the line loading the model tile data.
for(var/model_position = 1; model_position <= length(grid_line); model_position += key_len)
x_coordinate++
//Find the model key and load that model.
var/model_key = copytext(grid_line, model_position, model_position + key_len)
//If the key is the default one, skip it and save the computation time.
if(model_key == default_key)
continue
if(world.maxx < x_coordinate)
world.maxx = x_coordinate
parse_grid(grid_models[model_key], x_coordinate, y_coordinate, z_coordinate + z_offset)
if(prob(delay_chance))
sleep(1)
//If we hit the last tile in this z-level, we should break out of the loop.
if(grid_position + length(grid_line) + 1 > length(z_level))
break
//Break out of the loop when we hit the end of the file.
if(findtext(input_file, quote + "}", z_position) + 2 >= input_file_len)
break
proc/parse_grid(var/model as text, var/x_coordinate as num, var/y_coordinate as num, var/z_coordinate as num)
//Accepts a text string containing a comma separated list of type paths of the
// same construction as those contained in a .dmm file, and instantiates them.
var/list/text_strings = list()
for(var/index = 1; findtext(model, quote); index++)
/*Loop: Stores quoted portions of text in text_strings, and replaces them with an
index to that list.
- Each iteration represents one quoted section of text.
*/
//Add the next section of quoted text to the list
var/first_quote = findtext(model, quote)
var/second_quote = findtext(model, quote, first_quote + 1)
var/quoted_chunk = copytext(model, first_quote + 1, second_quote)
text_strings += quoted_chunk
//Then remove the quoted section.
model = copytext(model, 1, first_quote) + "~[index]" + copytext(model, second_quote + 1)
var/debug_output = 0
//if(x_coordinate == 86 && y_coordinate == 88 && z_coordinate == 7)
// debug_output = 1
if(debug_output)
debug_file << " Now debugging turf: [model] ([x_coordinate], [y_coordinate], [z_coordinate])"
var/next_position = 1
for(var/data_position = 1, next_position || data_position != 1, data_position = next_position + 1)
next_position = findtext(model, ",/", data_position)
var/full_def = copytext(model, data_position, next_position)
if(debug_output)
debug_file << " Current Line: [full_def] -- ([data_position] - [next_position])"
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- Each iteration represents one object's data, including type path and field values.
*/
//Load the attribute data.
var/attribute_position = findtext(full_def,"{")
var/atom_def = text2path(copytext(full_def, 1, attribute_position))
var/list/attributes = list()
if(attribute_position)
full_def = copytext(full_def, attribute_position + 1)
if(debug_output)
debug_file << " Atom Def: [atom_def]"
debug_file << " Parameters: [full_def]"
var/next_attribute = 1
for(attribute_position = 1, next_attribute || attribute_position != 1, attribute_position = next_attribute + 1)
next_attribute = findtext(full_def, ";", attribute_position)
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
attributes += copytext(full_def, attribute_position, next_attribute)
//Construct attributes associative list
var/list/fields = list()
for(var/attribute in attributes)
var/trim_left = trim_text(copytext(attribute, 1, findtext(attribute, "=")))
var/trim_right = trim_text(copytext(attribute, findtext(attribute, "=") + 1))
if(findtext(trim_right, "list("))
trim_right = get_list(trim_right, text_strings)
else if(findtext(trim_right, "~"))//Check for strings
while(findtext(trim_right,"~"))
var/reference_index = copytext(trim_right, findtext(trim_right, "~") + 1)
trim_right = text_strings[text2num(reference_index)]
//Check for numbers
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right, 2, length(trim_right)))
fields[trim_left] = trim_right
sleep(-1)
if(debug_output)
var/return_data = " Debug Fields:"
for(var/item in fields)
return_data += " [item] = [fields[item]];"
debug_file << return_data
//Begin Instanciation
var/atom/instance
if(ispath(atom_def,/area))
instance = locate(atom_def)
if(!istype(instance, atom_def))
instance = new atom_def
instance.contents.Add(locate(x_coordinate,y_coordinate,z_coordinate))
else
instance = new atom_def(locate(x_coordinate,y_coordinate,z_coordinate))
if(instance)
for(var/item in fields)
instance.vars[item] = fields[item]
else if(!(atom_def in borked_paths))
borked_paths += atom_def
var/return_data = " Failure [atom_def] @ ([x_coordinate], [y_coordinate], [z_coordinate]) fields:"
for(var/item in fields)
return_data += " [item] = [fields[item]];"
debug_file << return_data
ycrd--
sleep(-1)
return 1
var/list/borked_paths = list()
//reached End Of File
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len)
break
sleep(-1)
proc/trim_text(var/what as text)
while(length(what) && findtext(what, " ", 1, 2))
what = copytext(what, 2)
/**
* Fill a given tile with its area/turf/objects/mobs
* Variable model is one full map line (e.g /turf/unsimulated/wall{icon_state = "rock"},/area/mine/explored)
*
* WORKING :
*
* 1) Read the model string, member by member (delimiter is ',')
*
* 2) Get the path of the atom and store it into a list
*
* 3) a) Check if the member has variables (text within '{' and '}')
*
* 3) b) Construct an associative list with found variables, if any (the atom index in members is the same as its variables in members_attributes)
*
* 4) Instanciates the atom with its variables
*
*/
/dmm_suite/proc/parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num)
/*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them.
*/
while(length(what) && findtext(what, " ", length(what)))
what = copytext(what, 1, length(what))
var/list/members = list()//will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
var/list/members_attributes = list()//will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
return what
proc/get_list(var/text, var/list/text_strings)
//First, trim the data to just the list contents
var/list_start = findtext(text, "(") + 1
var/list_end = findtext(text, ")", list_start)
var/list_contents = copytext(text, list_start, list_end)
/////////////////////////////////////////////////////////
//Constructing members and corresponding variables lists
////////////////////////////////////////////////////////
//Then, we seperate it into the individual entries
var/index=1
var/old_position = 1
var/dpos
var/list/entries = list()
var/entry_end = 1
do
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
dpos= find_next_delimiter_position(model,old_position,",","{","}")//find next delimiter (comma here) that's not within {...}
for(var/entry_start = 1, entry_end || entry_start != 1, entry_start = entry_end + 1)
entry_end = findtext(list_contents, ",", entry_start)
entries += copytext(list_contents, entry_start, entry_end)
var/full_def = copytext(model,old_position,dpos)//full definition, e.g : /obj/foo/bar{variables=derp}
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))//path definition, e.g /obj/foo/bar
members.Add(atom_def)
old_position = dpos + 1
//Finally, we assemble the completed list.
var/list/final_list = list()
for(var/entry in entries)
var/equals_position = findtext(entry, "=")
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
var/list/fields = list()
if(equals_position)
var/trim_left = trim_text(copytext(entry, 1, equals_position))
var/trim_right = trim_text(copytext(entry, equals_position + 1))
var/variables_start = findtext(full_def,"{")
if(variables_start)//if there's any variable
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
fields = text2list(full_def,";")
if(findtext(trim_right, "list("))
trim_right = get_list(trim_right, text_strings)
//then fill the members_attributes list with the corresponding variables
members_attributes.len++
members_attributes[index++] = fields
else if(findtext(trim_right, "~"))//Check for strings
while(findtext(trim_right,"~"))
var/reference_index = copytext(trim_right, findtext(trim_right, "~") + 1)
trim_right = text_strings[text2num(reference_index)]
sleep(-1)
while(dpos != 0)
//Check for numbers
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right, 2, length(trim_right)))
////////////////
//Instanciation
////////////////
if(findtext(trim_left, "~"))//Check for strings
while(findtext(trim_left,"~"))
var/reference_index = copytext(trim_left, findtext(trim_left, "~") + 1)
trim_left = text_strings[text2num(reference_index)]
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
final_list[trim_left] = trim_right
//first instance the /area and remove it from the members list
var/length = members.len
var/atom/instance
var/dmm_suite/preloader/_preloader = new(members_attributes[length])//preloader for assigning set variables on atom creation
else
if(findtext(entry, "~"))//Check for strings
while(findtext(entry, "~"))
var/reference_index = copytext(entry, findtext(entry, "~") + 1)
entry = text_strings[text2num(reference_index)]
instance = locate(members[length])
instance.contents.Add(locate(xcrd,ycrd,zcrd))
//Check for numbers
else if(isnum(text2num(entry)))
entry = text2num(entry)
if(_preloader && instance)
_preloader.load(instance)
//Check for file
else if(copytext(entry, 1, 2) == "'")
entry = file(copytext(entry, 2, length(entry)))
members.Remove(members[length])
final_list += entry
//then instance the /turf and remove it from the members list
length = members.len
return final_list
instance_atom(members[length],members_attributes[length],xcrd,ycrd,zcrd)
members.Remove(members[length])
//Replace the previous part of the code with this if it's unsafe to assume tiles have ALWAYS an /area AND a /turf
/*while(members.len > 0)
var/length = members.len
var/member = members[length]
if(ispath(member,/area))
var/atom/instance
var/dmm_suite/preloader/_preloader = new(members_attributes[length])
instance = locate(member)
instance.contents.Add(locate(xcrd,ycrd,zcrd))
if(_preloader && instance)
_preloader.load(instance)
members.Remove(member)
continue
else if(ispath(member,/turf))
instance_atom(member,members_attributes[length],xcrd,ycrd,zcrd)
members.Remove(member)
continue
else
break
*/
//finally instance all remainings objects/mobs
for(var/k=1,k<=members.len,k++)
instance_atom(members[k],members_attributes[k],xcrd,ycrd,zcrd)
////////////////
//Helpers procs
////////////////
//Instance an atom at (x,y,z) and gives it the variables in attributes
/dmm_suite/proc/instance_atom(var/path,var/list/attributes, var/x, var/y, var/z)
var/atom/instance
var/dmm_suite/preloader/_preloader = new(attributes)
instance = new path (locate(x,y,z), _preloader)//first preloader pass
if(_preloader && instance)//second preloader pass, as some variables may have been reset/changed by New()
_preloader.load(instance)
//text trimming (both directions) helper proc
//optionally removes quotes before and after the text (for variable name)
/dmm_suite/proc/trim_text(var/what as text,var/trim_quotes=0)
while(length(what) && (findtext(what," ",1,2)))// || findtext(what,quote,1,2)))
what=copytext(what,2,0)
while(length(what) && (findtext(what," ",length(what),0)))// || findtext(what,quote,length(what),0)))
what=copytext(what,1,length(what))
if(trim_quotes)
while(length(what) && (findtext(what,quote,1,2)))
what=copytext(what,2,0)
while(length(what) && (findtext(what,quote,length(what),0)))
what=copytext(what,1,length(what))
return what
//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape
//returns 0 if reached the last delimiter
/dmm_suite/proc/find_next_delimiter_position(var/text as text,var/initial_position as num, var/delimiter=",",var/opening_escape=quote,var/closing_escape=quote)
var/position = initial_position
var/next_delimiter = findtext(text,delimiter,position,0)
var/next_opening = findtext(text,opening_escape,position,0)
while((next_opening != 0) && (next_opening < next_delimiter))
position = findtext(text,closing_escape,next_opening + 1,0)+1
next_delimiter = findtext(text,delimiter,position,0)
next_opening = findtext(text,opening_escape,position,0)
return next_delimiter
//build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
//return the filled list
/dmm_suite/proc/text2list(var/text as text,var/delimiter=",")
var/list/to_return = list()
var/position
var/old_position = 1
do
//find next delimiter that is not within "..."
position = find_next_delimiter_position(text,old_position,delimiter)
//check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7))
var/equal_position = findtext(text,"=",old_position, position)
var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position)),1)//the name of the variable, must trim quotes to build a BYOND compliant associatives list
old_position = position + 1
if(equal_position)//associative var, so do the association
var/trim_right = trim_text(copytext(text,equal_position+1,position))//the content of the variable
//Check for string
if(findtext(trim_right,quote,1,2))
trim_right = copytext(trim_right,2,findtext(trim_right,quote,3,0))
//Check for number
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right,2,length(trim_right)))
//Check for list
else if(copytext(trim_right,1,5) == "list")
trim_right = text2list(copytext(trim_right,6,length(trim_right)))
to_return[trim_left] = trim_right
else//simple var
to_return[trim_left] = null
while(position != 0)
return to_return
//atom creation method that preloads variables before creation
atom/New(atom/loc, dmm_suite/preloader/_dmm_preloader)
if(istype(_dmm_preloader, /dmm_suite/preloader))
_dmm_preloader.load(src)
. = ..()
//////////////////
//Preloader datum
//////////////////
/dmm_suite/preloader
parent_type = /datum
var/list/attributes
/dmm_suite/preloader/New(list/the_attributes)
.=..()
if(!the_attributes.len)
Del()
attributes = the_attributes
/dmm_suite/preloader/proc/load(atom/what)
for(var/attribute in attributes)
what.vars[attribute] = attributes[attribute]
Del()
@@ -5,12 +5,6 @@
icon = 'icons/mob/alien.dmi'
icon_state = "alien"
pass_flags = PASSTABLE
melee_damage_lower = 1
melee_damage_upper = 3
attacktext = "bites"
attack_sound = null
friendly = "nuzzles"
wall_smash = 0
health = 100
maxHealth = 100
@@ -14,128 +14,14 @@
updatehealth()
return
/mob/living/carbon/alien/attack_animal(mob/living/M as mob)
/mob/living/carbon/alien/attack_hand(mob/living/carbon/M as mob)
if(istype(M,/mob/living/simple_animal))
var/mob/living/simple_animal/S = M
if(S.melee_damage_upper == 0)
S.emote("[S.friendly] [src]")
else
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[S]</B> [S.attacktext] [src]!", 1)
var/damage = rand(S.melee_damage_lower, S.melee_damage_upper)
adjustBruteLoss(damage)
S.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [S.name] ([S.ckey])</font>")
updatehealth()
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M as mob)
if(!(istype(M, /mob/living/carbon/monkey))) return//Fix for aliens receiving double messages when attacking other aliens.
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
if (health > 0)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[M.name] has bit [src]!</B>"), 1)
adjustBruteLoss(rand(1, 3))
updatehealth()
return
/mob/living/carbon/alien/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
Weaken(5)
if (stuttering < 5)
stuttering = 5
Stun(5)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall.", 2)
return
else
M << "\red Not enough charge! "
return
switch(M.a_intent)
if ("help")
if (health > 0)
help_shake_act(M)
else
if (M.health >= -75.0)
if ((M.head && M.head.flags & 4) || (M.wear_mask && !( M.wear_mask.flags & 32 )) )
M << "\blue <B>Remove that mask!</B>"
return
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn( 0 )
O.process()
return
if ("grab")
if (M == src)
@@ -1,14 +1,15 @@
/mob/living/carbon/alien/diona/attack_hand(mob/living/carbon/human/M as mob)
//Let people pick the little buggers up.
if(M.a_intent == "help")
if(M.species && M.species.name == "Diona")
M << "You feel your being twine with that of [src] as it merges with your biomass."
src << "You feel your being twine with that of [M] as you merge with its biomass."
src.verbs += /mob/living/carbon/alien/diona/proc/split
src.verbs -= /mob/living/carbon/alien/diona/proc/merge
src.loc = M
else
get_scooped(M)
if(istype(M))
//Let people pick the little buggers up.
if(M.a_intent == "help")
if(M.species && M.species.name == "Diona")
M << "You feel your being twine with that of [src] as it merges with your biomass."
src << "You feel your being twine with that of [M] as you merge with its biomass."
src.verbs += /mob/living/carbon/alien/diona/proc/split
src.verbs -= /mob/living/carbon/alien/diona/proc/merge
src.loc = M
else
get_scooped(M)
..()
@@ -5,8 +5,6 @@
speak_emote = list("hisses")
icon_state = "larva"
language = "Hivemind"
melee_damage_lower = 3
melee_damage_upper = 6
amount_grown = 0
max_grown = 200
-16
View File
@@ -83,22 +83,6 @@
return
/mob/living/carbon/attack_paw(mob/M as mob)
if(!istype(M, /mob/living/carbon)) return
for(var/datum/disease/D in viruses)
if(D.spread_by_touch())
M.contract_disease(D, 0, 1, CONTACT_HANDS)
for(var/datum/disease/D in M.viruses)
if(D.spread_by_touch())
contract_disease(D, 0, 1, CONTACT_HANDS)
return
/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
@@ -24,10 +24,6 @@ var/const/MAX_ACTIVE_TIME = 400
var/strength = 5
var/attached = 0
/obj/item/clothing/mask/facehugger/attack_paw(user as mob) //can be picked up by aliens
attack_hand(user)
return
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
+12 -12
View File
@@ -64,56 +64,56 @@
tie_msg += " with \icon[U.hastie] \a [U.hastie]"
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][tie_msg]!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
//head
if(head)
if(head.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [t_his] head!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n"
//suit/armour
if(wear_suit)
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n"
//suit/armour storage
if(s_store && !skipsuitstorage)
if(s_store.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.</span>\n"
msg += "<span class='warning'>[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [t_his] back.</span>\n"
else
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
//left hand
if(l_hand)
if(l_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [t_his] left hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
//right hand
if(r_hand)
if(r_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [t_his] right hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
//gloves
if(gloves && !skipgloves)
if(gloves.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!</span>\n"
msg += "<span class='warning'>[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [t_his] hands!</span>\n"
else
msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n"
else if(blood_DNA)
@@ -131,14 +131,14 @@
//belt
if(belt)
if(belt.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!</span>\n"
msg += "<span class='warning'>[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [t_his] waist!</span>\n"
else
msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n"
//shoes
if(shoes && !skipshoes)
if(shoes.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!</span>\n"
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [t_his] feet!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n"
else if(feet_blood_DNA)
@@ -147,14 +147,14 @@
//mask
if(wear_mask && !skipmask)
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!</span>\n"
msg += "<span class='warning'>[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [t_his] face!</span>\n"
else
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
//eyes
if(glasses && !skipeyes)
if(glasses.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!</span>\n"
msg += "<span class='warning'>[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [t_his] eyes!</span>\n"
else
msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n"
+6 -87
View File
@@ -186,25 +186,6 @@
updatehealth()
return
/mob/living/carbon/human/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor)
if(armor >= 2) return
/mob/living/carbon/human/proc/implant_loyalty(mob/living/carbon/human/M, override = FALSE) // Won't override by default.
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
@@ -223,69 +204,6 @@
return 1
return 0
/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M as mob)
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(10, 35)
else
damage = rand(5, 25)
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
if(M.powerlevel > 0)
var/stunprob = 10
var/power = M.powerlevel + rand(0,3)
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] has shocked []!</B>", src), 1)
Weaken(power)
if (stuttering < power)
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/carbon/human/restrained()
if (handcuffed)
return 1
@@ -293,8 +211,6 @@
return 1
return 0
/mob/living/carbon/human/var/co2overloadtime = null
/mob/living/carbon/human/var/temperature_resistance = T0C+75
@@ -775,9 +691,12 @@
return number
/mob/living/carbon/human/IsAdvancedToolUser()
return species.has_fine_manipulation
/mob/living/carbon/human/IsAdvancedToolUser(var/silent)
if(species.has_fine_manipulation)
return 1
if(!silent)
src << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
return 0
/mob/living/carbon/human/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
@@ -1,93 +1,72 @@
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M as mob)
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
var/datum/organ/external/temp = M:organs_by_name["r_hand"]
if (M.hand)
temp = M:organs_by_name["l_hand"]
if(temp && !temp.is_usable())
M << "\red You can't use your [temp.display_name]."
return
var/mob/living/carbon/human/H = M
if(istype(H))
var/datum/organ/external/temp = H.organs_by_name["r_hand"]
if(H.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
H << "\red You can't use your [temp.display_name]."
return
..()
if((M != src) && check_shields(0, M.name))
visible_message("\red <B>[M] attempted to touch [src]!</B>")
return 0
// Should this all be in Touch()?
if(istype(H))
if((H != src) && check_shields(0, H.name))
visible_message("\red <B>[H] attempted to touch [src]!</B>")
return 0
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
visible_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Stungloved [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been stungloved by [M.name] ([M.ckey])</font>")
msg_admin_attack("[M.name] ([M.ckey]) stungloved [src.name] ([src.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[M.x];Y=[M.y];Z=[M.z]'>JMP</a>)")
var/armorblock = run_armor_check(M.zone_sel.selecting, "energy")
apply_effects(5,5,0,0,5,0,0,armorblock)
return 1
else
M << "\red Not enough charge! "
visible_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>")
return
if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove))
if(istype(H.gloves, /obj/item/clothing/gloves/boxing/hologlove))
var/damage = rand(0, 9)
if(!damage)
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] has attempted to punch [src]!</B>")
visible_message("\red <B>[H] has attempted to punch [src]!</B>")
return 0
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/datum/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
if(HULK in H.mutations)
damage += 5
playsound(loc, "punch", 25, 1, -1)
visible_message("\red <B>[M] has punched [src]!</B>")
visible_message("\red <B>[H] has punched [src]!</B>")
apply_damage(damage, HALLOSS, affecting, armor_block)
if(damage >= 9)
visible_message("\red <B>[M] has weakened [src]!</B>")
visible_message("\red <B>[H] has weakened [src]!</B>")
apply_effect(4, WEAKEN, armor_block)
return
else
if(istype(M,/mob/living/carbon))
// log_debug("No gloves, [M] is truing to infect [src]")
M.spread_disease_to(src, "Contact")
if(istype(M,/mob/living/carbon))
M.spread_disease_to(src, "Contact")
switch(M.a_intent)
if("help")
if(health >= config.health_threshold_crit)
if(istype(H) && health < config.health_threshold_crit)
if((H.head && (H.head.flags & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags & MASKCOVERSMOUTH)))
H << "\blue <B>Remove your mask!</B>"
return 0
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
H << "\blue <B>Remove [src]'s mask!</B>"
return 0
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human()
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn(0)
O.process()
else
help_shake_act(M)
return 1
// if(M.health < -75) return 0
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove your mask!</B>"
return 0
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove his mask!</B>"
return 0
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human()
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn(0)
O.process()
return 1
if("grab")
@@ -111,42 +90,43 @@
if("hurt")
if(!istype(H))
attack_generic(H,rand(1,3),"punched")
return
// See if they can attack, and which attacks to use.
var/datum/unarmed_attack/attack = M.species.unarmed
if(!attack.is_usable(M))
attack = M.species.secondary_unarmed
if(!attack.is_usable(M))
var/datum/unarmed_attack/attack = H.species.unarmed
if(!attack.is_usable(H))
attack = H.species.secondary_unarmed
if(!attack.is_usable(H))
return 0
M.attack_log += text("\[[time_stamp()]\] <font color='red'>[pick(attack.attack_verb)]ed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [pick(attack.attack_verb)]ed by [M.name] ([M.ckey])</font>")
msg_admin_attack("[key_name(M)] [pick(attack.attack_verb)]ed [key_name(src)]")
H.attack_log += text("\[[time_stamp()]\] <font color='red'>[pick(attack.attack_verb)]ed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [pick(attack.attack_verb)]ed by [H.name] ([M.ckey])</font>")
msg_admin_attack("[key_name(H)] [pick(attack.attack_verb)]ed [key_name(src)]")
var/damage = rand(0, 5)//BS12 EDIT
if(!damage)
playsound(loc, attack.miss_sound, 25, 1, -1)
visible_message("\red <B>[M] tried to [pick(attack.attack_verb)] [src]!</B>")
visible_message("\red <B>[H] tried to [pick(attack.attack_verb)] [src]!</B>")
return 0
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/datum/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
if(HULK in H.mutations) damage += 5
playsound(loc, attack.attack_sound, 25, 1, -1)
visible_message("\red <B>[M] [pick(attack.attack_verb)]ed [src]!</B>")
visible_message("\red <B>[H] [pick(attack.attack_verb)]ed [src]!</B>")
//Rearranged, so claws don't increase weaken chance.
if(damage >= 5 && prob(50))
visible_message("\red <B>[M] has weakened [src]!</B>")
visible_message("\red <B>[H] has weakened [src]!</B>")
apply_effect(3, WEAKEN, armor_block)
damage += attack.damage
apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge)
if("disarm")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Disarmed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been disarmed by [M.name] ([M.ckey])</font>")
@@ -222,4 +202,20 @@
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
return
return
/mob/living/carbon/human/attack_generic(var/mob/user, var/damage, var/attack_message)
if(!damage)
return
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [user.name] ([user.ckey])</font>")
src.visible_message("<span class='danger'>[user] has [attack_message] [src]!</span>")
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
updatehealth()
return 1
@@ -1,23 +0,0 @@
/mob/living/carbon/human/attack_paw(mob/M as mob)
..()
if (M.a_intent == "help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
for(var/mob/O in viewers(src, null))
O.show_message(text("\red <B>[M.name] has bit []!</B>", src), 1)
var/damage = rand(1, 3)
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
var/mob/living/carbon/human/H = src
src = null
src = H.monkeyize()
contract_disease(D,1,0)
return
@@ -55,6 +55,9 @@
if (bodytemperature < 283.222)
tally += (283.222 - bodytemperature) / 10 * 1.75
if(can_stand <= 1)
tally += 5 //hopping around on one foot is slow
if(mRun in mutations)
tally = 0
@@ -83,7 +83,7 @@
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
UnarmedAttack(Target)
return
if(!Target.lying && prob(80))
@@ -94,7 +94,7 @@
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
UnarmedAttack(Target)
else
if(!Atkcool && Target.Adjacent(src))
@@ -119,7 +119,7 @@
if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
if(nutrition <= get_hunger_nutrition() && !Atkcool)
if (is_adult || prob(5))
AM.attack_slime(src)
UnarmedAttack(AM)
spawn()
Atkcool = 1
sleep(45)
@@ -253,84 +253,7 @@
updatehealth()
return
/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (Victim) return // can't attack while eating!
if (health > -100)
visible_message("<span class='danger'> The [M.name] has glomped [src]!</span>", \
"<span class='userdanger'> The [M.name] has glomped [src]!</span>")
var/damage = rand(1, 3)
attacked += 5
if(M.is_adult)
damage = rand(1, 6)
else
damage = rand(1, 3)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/slime/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='danger'>[M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
attacked += 10
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/slime/attack_paw(mob/living/carbon/monkey/M as mob)
if(!(istype(M, /mob/living/carbon/monkey)))
return // Fix for aliens receiving double messages when attacking other aliens.
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
if (health > 0)
attacked += 10
//playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M.name] has attacked [src]!</span>", \
"<span class='userdanger'>[M.name] has attacked [src]!</span>")
adjustBruteLoss(rand(1, 3))
updatehealth()
return
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
@@ -387,18 +310,6 @@
return
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
visible_message("<span class='warning'>[src] has been touched with the stun gloves by [M]!</span>")
return
else
M << "\red Not enough charge! "
return
switch(M.a_intent)
if ("help")
@@ -21,3 +21,16 @@
return 1
return ..()
/mob/living/carbon/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if (speaker in Friends)
speech_buffer = list()
speech_buffer.Add(speaker)
speech_buffer.Add(lowertext(html_decode(message)))
..()
/mob/living/carbon/slime/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
if (speaker in Friends)
speech_buffer = list()
speech_buffer.Add(speaker)
speech_buffer.Add(lowertext(html_decode(message)))
..()
+5 -130
View File
@@ -143,58 +143,7 @@
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
return
//mob/living/carbon/monkey/bullet_act(var/obj/item/projectile/Proj)taken care of in living
/mob/living/carbon/monkey/attack_paw(mob/M as mob)
..()
if (M.a_intent == "help")
help_shake_act(M)
else
if ((M.a_intent == "hurt" && !( istype(wear_mask, /obj/item/clothing/mask/muzzle) )))
if ((prob(75) && health > 0))
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M.name] has bit [name]!</B>", 1)
var/damage = rand(1, 5)
adjustBruteLoss(damage)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
contract_disease(D,1,0)
else
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M.name] has attempted to bite [name]!</B>", 1)
return
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
Weaken(5)
if (stuttering < 5)
stuttering = 5
Stun(5)
for(var/mob/O in viewers(src, null))
if (O.client)
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall", 2)
return
else
M << "\red Not enough charge! "
return
if (M.a_intent == "help")
help_shake_act(M)
@@ -254,82 +203,6 @@
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
return
/mob/living/carbon/monkey/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/monkey/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
if(M.powerlevel > 0)
var/stunprob = 10
var/power = M.powerlevel + rand(0,3)
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] has shocked []!</B>", src), 1)
Weaken(power)
if (stuttering < power)
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/carbon/monkey/Stat()
..()
statpanel("Status")
@@ -393,8 +266,10 @@
del(src)
return
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
//Unless its monkey mode monkeys cant use advanced tools
/mob/living/carbon/monkey/IsAdvancedToolUser(var/silent)
if(!silent)
src << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
return 0
/mob/living/carbon/monkey/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list())
@@ -412,4 +287,4 @@
message = capitalize(trim_left(message))
..(message, speaking, verb, alt_name, italics, message_range, used_radios)
..(message, speaking, verb, alt_name, italics, message_range, used_radios)
+12
View File
@@ -179,3 +179,15 @@
return 0
// End BS12 momentum-transfer code.
/mob/living/attack_generic(var/mob/user, var/damage, var/attack_message)
if(!damage)
return
adjustBruteLoss(damage)
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [user.name] ([user.ckey])</font>")
src.visible_message("<span class='danger'>[user] has [attack_message] [src]!</span>")
spawn(1) updatehealth()
return 1
+1 -9
View File
@@ -37,12 +37,4 @@
var/tod = null // Time of death
var/update_slimes = 1
var/silent = null //Can't talk. Value goes down every life proc.
// Putting these here for attack_animal().
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles"
var/wall_smash = 0
var/silent = null //Can't talk. Value goes down every life proc.
-6
View File
@@ -117,12 +117,6 @@ proc/get_radio_key_from_channel(var/channel)
hearturfs += M.locs[1]
for(var/obj/O in M.contents)
listening_obj |= O
if (isslime(I))
var/mob/living/carbon/slime/S = I
if (src in S.Friends)
S.speech_buffer = list()
S.speech_buffer.Add(src)
S.speech_buffer.Add(lowertext(html_decode(message)))
else if(istype(I, /obj/))
var/obj/O = I
hearturfs += O.locs[1]
-14
View File
@@ -542,20 +542,6 @@ var/list/ai_verbs_default = list(
updatehealth()
return 2
/mob/living/silicon/ai/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/silicon/ai/reset_view(atom/A)
if(camera)
camera.SetLuminosity(0)
@@ -12,8 +12,8 @@
w_class = 2.0
throw_speed = 5
throw_range = 10
matter = list("metal" = 200)
origin_tech = "magnets=1;biotech=1"
matter = list("metal" = 500, "glass" = 200)
origin_tech = "magnets=2;biotech=1;engineering=2"
var/mode = 1;
/obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
@@ -14,11 +14,6 @@
/obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/drone_control/attack_paw(var/mob/user as mob)
return src.attack_hand(user)
return
/obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob)
if(..())
return
+4 -75
View File
@@ -871,81 +871,6 @@ var/list/robot_verbs_default = list(
spark_system.start()
return ..()
/mob/living/silicon/robot/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
damage = round(damage / 2) // borgs recieve half damage
adjustBruteLoss(damage)
if(M.powerlevel > 0)
var/stunprob = 10
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] has electrified []!</B>", src), 1)
flick("noise", flash)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (prob(stunprob) && M.powerlevel >= 8)
adjustBruteLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/silicon/robot/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/silicon/robot/attack_hand(mob/user)
add_fingerprint(user)
@@ -967,6 +892,10 @@ var/list/robot_verbs_default = list(
user << "You remove \the [broken_device]."
user.put_in_active_hand(broken_device)
//Robots take half damage from basic attacks.
/mob/living/silicon/robot/attack_generic(var/mob/user, var/damage, var/attack_message)
return ..(user,Floor(damage/2),attack_message)
/mob/living/silicon/robot/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(check_access(null))
@@ -23,10 +23,10 @@
return tally+config.robot_delay
// NEW: Use power while moving.
/mob/living/silicon/robot/Move()
/mob/living/silicon/robot/SelfMove(turf/n, direct)
if (!is_component_functioning("actuator"))
return
return 0
var/datum/robot_component/actuator/A = get_component("actuator")
if (cell_use_power(A.active_usage))
..()
return ..()
@@ -16,7 +16,7 @@
a_intent = "harm"
stop_automated_movement = 1
status_flags = CANPUSH
attacktext = "nips"
attacktext = "nipped"
friendly = "prods"
wander = 0
pass_flags = PASSTABLE
@@ -214,9 +214,9 @@
if(chemicals < 50)
src << "You don't have enough chemicals!"
var/chem = input("Select a chemical to secrete.", "Chemicals") in list("bicaridine","tramadol","hyperzine","alkysine")
var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol")
if(chemicals < 50 || !host || controlling || !src || stat) //Sanity check.
if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check.
return
src << "\red <B>You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream.</B>"
@@ -86,25 +86,6 @@
step(AM, t)
now_pushing = null
/mob/living/simple_animal/construct/attack_animal(mob/living/M as mob)
if(istype(M, /mob/living/simple_animal/construct/builder))
health += 5
M.emote("mends some of \the <EM>[src]'s</EM> wounds.")
else
if(M.melee_damage_upper <= 0)
M.emote("[M.friendly] \the <EM>[src]</EM>")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("<span class='attack'>\The <EM>[M]</EM> [M.attacktext] \the <EM>[src]</EM>!</span>", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
var/damage = O.force
@@ -139,7 +120,7 @@
harm_intent_damage = 0
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "smashes their armoured gauntlet into"
attacktext = "smashed their armoured gauntlet into"
speed = 3
wall_smash = 1
attack_sound = 'sound/weapons/punch3.ogg'
@@ -214,7 +195,7 @@
health = 75
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashes"
attacktext = "slashed"
speed = -1
see_in_dark = 7
attack_sound = 'sound/weapons/bladeslice.ogg'
@@ -239,7 +220,7 @@
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "rams"
attacktext = "rammed"
speed = 0
wall_smash = 1
attack_sound = 'sound/weapons/punch2.ogg'
@@ -266,7 +247,7 @@
harm_intent_damage = 0
melee_damage_lower = 50
melee_damage_upper = 50
attacktext = "brutally crushes"
attacktext = "brutally crushed"
speed = 5
wall_smash = 1
attack_sound = 'sound/weapons/punch4.ogg'
@@ -308,10 +308,9 @@
dir = SOUTH
if(isturf(movement_target.loc) )
movement_target.attack_animal(src)
else if(ishuman(movement_target.loc) )
if(prob(20))
emote("stares at the [movement_target] that [movement_target.loc] has with a sad puppy-face")
UnarmedAttack(movement_target)
else if(ishuman(movement_target.loc) && prob(20))
custom_emote(1,"stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.")
if(prob(1))
emote(pick("dances around","chases its tail"))
@@ -18,7 +18,7 @@
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
faction = "goat"
attacktext = "kicks"
attacktext = "kicked"
health = 40
melee_damage_lower = 1
melee_damage_upper = 5
@@ -102,7 +102,7 @@
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
attacktext = "kicked"
health = 50
var/datum/reagents/udder = null
@@ -163,7 +163,7 @@
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
attacktext = "kicked"
health = 1
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE
@@ -204,7 +204,7 @@ var/global/chicken_count = 0
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
attacktext = "kicked"
health = 10
var/eggsleft = 0
var/body_color
@@ -9,8 +9,7 @@
speak_emote = list("hisses")
health = 5
maxHealth = 5
attacktext = "bites"
attacktext = "bites"
attacktext = "bitten"
melee_damage_lower = 1
melee_damage_upper = 2
response_help = "pets"
@@ -26,8 +26,7 @@
health = 10
maxHealth = 10
attacktext = "shocks"
attacktext = "shocks"
attacktext = "shocked"
melee_damage_lower = 1
melee_damage_upper = 3
@@ -16,7 +16,7 @@
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashes"
attacktext = "slashed"
a_intent = "harm"
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 0
@@ -141,10 +141,10 @@
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
else if(istype(target_mob,/obj/mecha))
var/obj/mecha/M = target_mob
M.attack_animal(src)
return M
//else if(istype(target_mob,/obj/mecha))
//var/obj/mecha/M = target_mob
//M.attack_animal(src)
//return M
@@ -20,7 +20,7 @@
harm_intent_damage = 8
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "bites"
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
@@ -10,7 +10,7 @@
maxHealth = 80
melee_damage_lower = 25
melee_damage_upper = 50
attacktext = "chomps"
attacktext = "chomped"
attack_sound = 'sound/weapons/bite.ogg'
faction = "creature"
speed = 4
@@ -16,7 +16,7 @@
harm_intent_damage = 10
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "grips"
attacktext = "gripped"
attack_sound = 'sound/hallucinations/growl1.ogg'
min_oxy = 0
@@ -13,7 +13,7 @@
maxHealth = 15
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
attacktext = "clawed"
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = "hivebot"
@@ -89,17 +89,17 @@
/mob/living/simple_animal/hostile/proc/AttackingTarget()
if(!Adjacent(target_mob))
return
if(isliving(target_mob))
var/mob/living/L = target_mob
L.attack_animal(src)
return L
if(istype(target_mob,/obj/mecha))
var/obj/mecha/M = target_mob
M.attack_animal(src)
return M
if(istype(target_mob,/obj/machinery/bot))
var/obj/machinery/bot/B = target_mob
B.attack_animal(src)
//if(isliving(target_mob))
//var/mob/living/L = target_mob
//L.attack_animal(src)
//return L
//if(istype(target_mob,/obj/mecha))
//var/obj/mecha/M = target_mob
//M.attack_animal(src)
//return M
//if(istype(target_mob,/obj/machinery/bot))
//var/obj/machinery/bot/B = target_mob
//B.attack_animal(src)
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE
@@ -193,10 +193,10 @@
/mob/living/simple_animal/hostile/proc/DestroySurroundings()
if(prob(break_stuff_probability))
for(var/dir in cardinal) // North, South, East, West
for(var/obj/structure/window/obstacle in get_step(src, dir))
if(obstacle.dir == reverse_dir[dir]) // So that windows get smashed in the right order
obstacle.attack_animal(src)
return
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
obstacle.attack_animal(src)
//for(var/obj/structure/window/obstacle in get_step(src, dir))
//if(obstacle.dir == reverse_dir[dir]) // So that windows get smashed in the right order
//obstacle.attack_animal(src)
//return
//var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
//if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
//obstacle.attack_animal(src)
@@ -20,7 +20,7 @@
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "attacks"
attacktext = "attacked"
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
@@ -56,7 +56,7 @@
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
/mob/living/simple_animal/hostile/mimic/crate
attacktext = "bites"
attacktext = "bitten"
stop_automated_movement = 1
wander = 0
@@ -17,7 +17,7 @@
harm_intent_damage = 5
melee_damage_lower = 30
melee_damage_upper = 30
attacktext = "slashes"
attacktext = "slashed"
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 5
@@ -21,7 +21,7 @@
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "attacks"
attacktext = "attacked"
attack_sound = 'sound/items/bikehorn.ogg'
min_oxy = 5
@@ -17,7 +17,7 @@
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "punches"
attacktext = "punched"
a_intent = "harm"
var/corpse = /obj/effect/landmark/mobcorpse/russian
var/weapon1 = /obj/item/weapon/kitchenknife
@@ -17,7 +17,7 @@
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "punches"
attacktext = "punched"
a_intent = "harm"
var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
var/weapon1
@@ -55,7 +55,7 @@
icon_living = "syndicatemelee"
weapon1 = /obj/item/weapon/melee/energy/sword/red
weapon2 = /obj/item/weapon/shield/energy
attacktext = "slashes"
attacktext = "slashed"
status_flags = 0
/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -144,7 +144,7 @@
maxHealth = 15
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "cuts"
attacktext = "cut"
attack_sound = 'sound/weapons/bladeslice.ogg'
faction = "syndicate"
min_oxy = 0
@@ -21,7 +21,7 @@
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "bites"
attacktext = "bitten"
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
+18 -16
View File
@@ -232,22 +232,6 @@
drop_held_item(0)
return
/mob/living/simple_animal/parrot/attack_paw(mob/living/carbon/monkey/M as mob)
attack_hand(M)
//Simple animals
/mob/living/simple_animal/parrot/attack_animal(mob/living/M as mob)
if(client) return
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
if(M.melee_damage_upper > 0)
parrot_interest = M
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
icon_state = "parrot_fly"
//Mobs with objects
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob)
..()
@@ -753,3 +737,21 @@
if(!message || stat)
return
speech_buffer.Add(message)
/mob/living/simple_animal/parrot/attack_generic(var/mob/user, var/damage, var/attack_message)
var/success = ..()
if(client)
return success
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
if(!success)
return 0
parrot_interest = user
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
icon_state = "parrot_fly"
return success
@@ -16,7 +16,7 @@
response_harm = "punches the"
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "drains the life from"
attacktext = "drained the life from"
minbodytemp = 0
maxbodytemp = 4000
min_oxy = 0
@@ -47,11 +47,12 @@
var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
melee_damage_lower = 0
melee_damage_upper = 0
attacktext = "attacks"
attack_sound = null
friendly = "nuzzles" //If the mob does no damage with it's attack
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/attacktext = "attacked"
var/attack_sound = null
var/friendly = "nuzzles"
var/wall_smash = 0
/mob/living/simple_animal/New()
..()
@@ -209,19 +210,6 @@
if(act == "scream") act = "whimper" //ugly hack to stop animals screaming when crushed :P
..(act, type, desc)
/mob/living/simple_animal/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj || Proj.nodamage)
return
@@ -266,29 +254,6 @@
return
/mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
visible_message("\red <B>The [M.name] glomps [src]!</B>")
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
return
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/stack/medical))
@@ -57,7 +57,7 @@
melee_damage_lower = 10
melee_damage_upper = 15
attacktext = "bites"
attacktext = "bitten"
animate_movement = SLIDE_STEPS
+16 -15
View File
@@ -847,17 +847,18 @@ note dizziness decrements automatically in the mob's Life() proc.
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(buckled)
if (!buckled.movable)
anchored = 1
canmove = 0
if(istype(buckled,/obj/structure/stool/bed/chair) )
lying = 0
else
lying = 1
else
lying = 1
else if (buckled && (buckled.movable))
anchored = 0
canmove = 1
lying = 0
anchored = 0
canmove = 1
lying = 0
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
@@ -867,9 +868,9 @@ note dizziness decrements automatically in the mob's Life() proc.
anchored = 1
canmove = 0
lying = 0
else if (!buckled)
lying = !can_stand
canmove = has_limbs
else
lying = 0
canmove = 1
if(lying)
density = 0
@@ -920,10 +921,10 @@ note dizziness decrements automatically in the mob's Life() proc.
return facedir(SOUTH)
/mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check
//This might need a rename but it should replace the can this mob use things check
/mob/proc/IsAdvancedToolUser()
return 0
/mob/proc/Stun(amount)
if(status_flags & CANSTUN)
stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
+2 -3
View File
@@ -213,11 +213,10 @@
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
var/universal_understand = 0 // Set to 1 to enable the mob to understand everyone, not necessarily speak
var/has_limbs = 1 //Whether this mob have any limbs he can move with
var/can_stand = 1 //Whether this mob have ability to stand
var/can_stand = 2 //Whether this mob have ability to stand
var/immune_to_ssd = 0
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/active_genes=list()
var/list/active_genes=list()
+4 -1
View File
@@ -316,7 +316,7 @@
else if(mob.confused)
step(mob, pick(cardinal))
else
. = ..()
. = mob.SelfMove(n, direct)
moving = 0
@@ -324,6 +324,9 @@
return
/mob/proc/SelfMove(turf/n, direct)
return Move(n, direct)
///Process_Grab()
///Called by client/Move()
+20 -6
View File
@@ -302,8 +302,8 @@
job_master.AssignRole(src, rank, 1)
var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind
job_master.EquipRank(character, rank, 1) //equips the human
var/mob/living/character = create_character() //creates the human and transfers vars and mind
character = job_master.EquipRank(character, rank, 1) //equips the human
UpdateFactionList(character)
EquipCustomItems(character)
@@ -315,8 +315,13 @@
S = spawntypes[spawning_at]
if(S && istype(S))
character.loc = pick(S.turfs)
join_message = S.msg
if(S.check_job_spawning(rank))
character.loc = pick(S.turfs)
join_message = S.msg
else
character << "Your chosen spawnpoint ([S.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."
character.loc = pick(latejoin)
join_message = "has arrived on the station"
else
character.loc = pick(latejoin)
join_message = "has arrived on the station"
@@ -338,9 +343,9 @@
//Grab some data from the character prefs for use in random news procs.
AnnounceArrival(character, rank, join_message)
else
character.Robotize()
AnnounceCyborg(character, rank, join_message)
del(src)
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
@@ -351,6 +356,15 @@
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
del(a)
proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI.
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
a.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
del(a)
proc/LateChoices()
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
+15 -19
View File
@@ -60,7 +60,6 @@
/mob/living/carbon/human/proc/handle_organs()
number_wounds = 0
var/leg_tally = 2
var/force_process = 0
var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss()
if(damage_this_tick > last_dam)
@@ -75,6 +74,9 @@
for(var/datum/organ/internal/I in internal_organs)
I.process()
//losing a limb stops it from processing, so this has to be done separately
handle_stance()
if(!force_process && !bad_external_organs.len)
return
@@ -101,23 +103,17 @@
if (W.infection_check())
W.germ_level += 1
if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
/mob/living/carbon/human/proc/handle_stance()
can_stand = 2
for (var/organ in list("l_leg","l_foot","r_leg","r_foot"))
var/datum/organ/external/E = organs_by_name[organ]
if ((E.status & ORGAN_DESTROYED) || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable())
can_stand-- // let it fail even if just foot&leg
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
if(species && species.flags & NO_PAIN)
emote("scream")
emote("collapse")
paralysis = 10
//Check arms and legs for existence
can_stand = 2 //can stand on both legs
var/datum/organ/external/E = organs_by_name["l_foot"]
if(E.status & ORGAN_DESTROYED)
can_stand--
E = organs_by_name["r_foot"]
if(E.status & ORGAN_DESTROYED)
can_stand--
if(can_stand <= 0)
Weaken(10)
if (!(lying || resting))
if(species && !(species.flags & NO_PAIN))
emote("scream")
emote("collapse")
-5
View File
@@ -21,11 +21,6 @@
return
/obj/item/weapon/paper_bin/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/item/weapon/paper_bin/attack_hand(mob/user as mob)
if (hasorgans(user))
var/datum/organ/external/temp = user:organs_by_name["r_hand"]
-3
View File
@@ -18,9 +18,6 @@
attack_ai(mob/user as mob)
return attack_hand(user)
attack_paw(mob/user as mob)
return attack_hand(user)
attack_hand(mob/user as mob)
user.set_machine(src)
-5
View File
@@ -64,12 +64,7 @@
icon_state = "stamp-cent"
item_color = "centcomm"
/obj/item/weapon/stamp/attack_paw(mob/user as mob)
return attack_hand(user)
// Syndicate stamp to forge documents.
/obj/item/weapon/stamp/chameleon/attack_self(mob/user as mob)
var/list/stamp_types = typesof(/obj/item/weapon/stamp) - src.type // Get all stamp types except our own

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