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

Conflicts:
	code/game/objects/items/devices/telecrystal.dm
	icons/mob/suit.dmi
	icons/obj/clothing/suits.dmi
This commit is contained in:
SinTwo
2016-07-22 23:39:19 -04:00
69 changed files with 762 additions and 325 deletions

View File

@@ -37,5 +37,5 @@
// Chemistry lists.
var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate.
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate.
var/list/heartstopper = list("potassium_phorochloride", "zombie_powder") // This stops the heart.
var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional

View File

@@ -85,7 +85,7 @@ var/list/be_special_flags = list(
#define MODE_TRAITOR "traitor"
#define MODE_AUTOTRAITOR "autotraitor"
#define DEFAULT_TELECRYSTAL_AMOUNT 12
#define DEFAULT_TELECRYSTAL_AMOUNT 120
/////////////////
////WIZARD //////

View File

@@ -140,5 +140,5 @@
#define ui_iarrowleft "SOUTH-1,EAST-4"
#define ui_iarrowright "SOUTH-1,EAST-2"
#define ui_spell_master "EAST-1:16,NORTH-1:16"
#define ui_spell_master "EAST-2:16,NORTH-1:26"
#define ui_genetic_master "EAST-1:16,NORTH-3:16"

View File

@@ -102,6 +102,15 @@ var/global/list/all_exonet_connections = list()
return exonet.address
return null
// Proc: get_atom_from_address()
// Parameters: 1 (target_address - the desired address to find)
// Description: Searches an address for the atom it is attached for, otherwise returns null.
/datum/exonet_protocol/proc/get_atom_from_address(var/target_address)
for(var/datum/exonet_protocol/exonet in all_exonet_connections)
if(exonet.address == target_address)
return exonet.holder
return null
// Proc: send_message()
// Parameters: 3 (target_address - the desired address to send the message to, message - the message to send, text - the message text if message is of type "text")
// Description: Sends the message to target_address, by calling receive_message() on the desired datum.

View File

@@ -72,7 +72,7 @@
containername = "Emitter crate"
access = access_ce
/datum/supply_packs/engine/eng/field_gen
/datum/supply_packs/eng/engine/field_gen
name = "Field Generator crate"
contains = list(/obj/machinery/field_generator = 2)
containertype = /obj/structure/closet/crate/secure

View File

@@ -309,7 +309,6 @@
/obj/item/clothing/under/rank/security2 = 4,
/obj/item/clothing/under/rank/warden,
/obj/item/clothing/under/rank/head_of_security,
/obj/item/clothing/suit/armor/hos/jensen,
/obj/item/clothing/head/soft/sec = 4,
/obj/item/clothing/gloves/black = 4,
/obj/item/weapon/storage/box/holobadge

View File

@@ -2,7 +2,7 @@
* Ammunition *
*************/
/datum/uplink_item/item/ammo
item_cost = 2
item_cost = 20
category = /datum/uplink_category/ammunition
/datum/uplink_item/item/ammo/a357
@@ -63,7 +63,7 @@
/datum/uplink_item/item/ammo/s762
name = "10rnd Rifle Magazine (7.62mm)"
path = /obj/item/ammo_magazine/s762
item_cost = 1 // Half the capacity.
item_cost = 10 // Half the capacity.
/datum/uplink_item/item/ammo/s762/ap
name = "10rnd Rifle Magazine (7.62mm AP)"
@@ -88,7 +88,7 @@
/datum/uplink_item/item/ammo/g12/beanbag
name = "12g Auto-Shotgun Magazine (Beanbag)"
path = /obj/item/ammo_magazine/g12/beanbag
item_cost = 1 // Discount due to it being LTL.
item_cost = 10 // Discount due to it being LTL.
/datum/uplink_item/item/ammo/g12/pellet
name = "12g Auto-Shotgun Magazine (Pellet)"

View File

@@ -33,7 +33,7 @@
/datum/uplink_item/abstract/announcements/fake_crew_arrival
name = "Crew Arrival Announcement/Records"
desc = "Creates a fake crew arrival announcement as well as fake crew records, using your current appearance (including held items!) and worn id card. Trigger with care!"
item_cost = 4
item_cost = 40
/datum/uplink_item/abstract/announcements/fake_crew_arrival/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
if(!user)
@@ -91,7 +91,7 @@
/datum/uplink_item/abstract/announcements/fake_ion_storm
name = "Ion Storm Announcement"
desc = "Interferes with the station's ion sensors. Triggers immediately upon investment."
item_cost = 1
item_cost = 10
/datum/uplink_item/abstract/announcements/fake_ion_storm/get_goods(var/obj/item/device/uplink/U, var/loc)
ion_storm_announcement()
@@ -100,7 +100,7 @@
/datum/uplink_item/abstract/announcements/fake_radiation
name = "Radiation Storm Announcement"
desc = "Interferes with the station's radiation sensors. Triggers immediately upon investment."
item_cost = 3
item_cost = 30
/datum/uplink_item/abstract/announcements/fake_radiation/get_goods(var/obj/item/device/uplink/U, var/loc)
var/datum/event_meta/EM = new(EVENT_LEVEL_MUNDANE, "Fake Radiation Storm", add_to_queue = 0)

View File

@@ -6,10 +6,10 @@
/datum/uplink_item/item/armor/combat
name = "Combat Armor Set"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/storage/box/syndie_kit/combat_armor
/datum/uplink_item/item/armor/heavy_vest
name = "Heavy Armor Vest"
item_cost = 4
item_cost = 40
path = /obj/item/clothing/suit/storage/vest/heavy/merc

View File

@@ -53,8 +53,8 @@
****************/
/datum/uplink_item/item/badassery/surplus
name = "Surplus Crate"
item_cost = 40
var/item_worth = 60
item_cost = 400
var/item_worth = 600
var/icon
/datum/uplink_item/item/badassery/surplus/New()

View File

@@ -6,30 +6,30 @@
/datum/uplink_item/item/grenades/anti_photon
name = "5xPhoton Disruption Grenades"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/storage/box/anti_photons
/datum/uplink_item/item/grenades/emp
name = "5xEMP Grenades"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/emps
/datum/uplink_item/item/grenades/smoke
name = "7xSmoke Grenades"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/storage/box/smokes
/datum/uplink_item/item/grenades/frags
name = "5xFrag Grenades"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/storage/box/frags
/datum/uplink_item/item/grenades/flashbnags
name = "7xFlashbangs"
item_cost = 4
item_cost = 40
path = /obj/item/weapon/storage/box/flashbangs
/datum/uplink_item/item/grenades/metalfoam
name = "7xMetal Foam Grenades"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/metalfoam

View File

@@ -6,35 +6,35 @@
/datum/uplink_item/item/hardsuit_modules/thermal
name = "Thermal Scanner"
item_cost = 2
item_cost = 20
path = /obj/item/rig_module/vision/thermal
/datum/uplink_item/item/hardsuit_modules/energy_net
name = "Net Projector"
item_cost = 3
item_cost = 30
path = /obj/item/rig_module/fabricator/energy_net
/datum/uplink_item/item/ewar_voice
name = "Electrowarfare Suite and Voice Synthesiser"
item_cost = 4
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/ewar_voice
/datum/uplink_item/item/hardsuit_modules/maneuvering_jets
name = "Maneuvering Jets"
item_cost = 4
item_cost = 40
path = /obj/item/rig_module/maneuvering_jets
/datum/uplink_item/item/hardsuit_modules/egun
name = "Mounted Energy Gun"
item_cost = 6
item_cost = 60
path = /obj/item/rig_module/mounted/egun
/datum/uplink_item/item/hardsuit_modules/power_sink
name = "Power Sink"
item_cost = 6
item_cost = 60
path = /obj/item/rig_module/power_sink
/datum/uplink_item/item/hardsuit_modules/laser_canon
name = "Mounted Laser Cannon"
item_cost = 8
item_cost = 80
path = /obj/item/rig_module/mounted

View File

@@ -6,20 +6,20 @@
/datum/uplink_item/item/implants/imp_freedom
name = "Freedom Implant"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/imp_freedom
/datum/uplink_item/item/implants/imp_compress
name = "Compressed Matter Implant"
item_cost = 4
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_compress
/datum/uplink_item/item/implants/imp_explosive
name = "Explosive Implant (DANGER!)"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/storage/box/syndie_kit/imp_explosive
/datum/uplink_item/item/implants/imp_uplink
name = "Uplink Implant" //Original name: "Uplink Implant (Contains 5 Telecrystals)"
item_cost = 5 //Original cost: 10
item_cost = 50 //Original cost: 10
path = /obj/item/weapon/storage/box/syndie_kit/imp_uplink

View File

@@ -6,31 +6,31 @@
/datum/uplink_item/item/medical/sinpockets
name = "Box of Sin-Pockets"
item_cost = 1
item_cost = 10
path = /obj/item/weapon/storage/box/sinpockets
/datum/uplink_item/item/medical/surgery
name = "Surgery kit"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/storage/firstaid/surgery
/datum/uplink_item/item/medical/combat
name = "Combat medical kit"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/storage/firstaid/combat
/datum/uplink_item/item/medical/freezer
name = "Portable Freezer"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/storage/box/freezer
/datum/uplink_item/item/medical/ambrosiaseeds
name = "Box of 7x ambrosia seed packets"
item_cost = 1
item_cost = 10
path = /obj/item/weapon/storage/box/ambrosia
/datum/uplink_item/item/medical/ambrosiadeusseeds
name = "Box of 7x ambrosia deus seed packets"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/storage/box/ambrosiadeus

View File

@@ -6,40 +6,40 @@
/datum/uplink_item/item/stealth_items/id
name = "Agent ID card"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/card/id/syndicate
/datum/uplink_item/item/stealth_items/syndigaloshes
name = "No-Slip Shoes"
item_cost = 2
item_cost = 20
path = /obj/item/clothing/shoes/syndigaloshes
/datum/uplink_item/item/stealth_items/spy
name = "Bug Kit"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/storage/box/syndie_kit/spy
/datum/uplink_item/item/stealth_items/chameleon_kit
name = "Chameleon Kit"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/chameleon
/datum/uplink_item/item/stealth_items/chameleon_projector
name = "Chameleon-Projector"
item_cost = 4
item_cost = 40
path = /obj/item/device/chameleon
/datum/uplink_item/item/stealth_items/chameleon_projector
name = "Chameleon-Projector"
item_cost = 4
item_cost = 40
path = /obj/item/device/chameleon
/datum/uplink_item/item/stealth_items/voice
name = "Voice Changer"
item_cost = 4
item_cost = 40
path = /obj/item/clothing/mask/gas/voice
/datum/uplink_item/item/stealth_items/camera_floppy
name = "Camera Network Access - Floppy"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/disk/file/cameras/syndicate

View File

@@ -6,30 +6,30 @@
/datum/uplink_item/item/stealthy_weapons/soap
name = "Subversive Soap"
item_cost = 1
item_cost = 10
path = /obj/item/weapon/soap/syndie
/datum/uplink_item/item/stealthy_weapons/concealed_cane
name = "Concealed Cane Sword"
item_cost = 1
item_cost = 10
path = /obj/item/weapon/cane/concealed
/datum/uplink_item/item/stealthy_weapons/detomatix
name = "Detomatix PDA Cartridge"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/cartridge/syndicate
/datum/uplink_item/item/stealthy_weapons/parapen
name = "Paralysis Pen"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/pen/reagent/paralysis
/datum/uplink_item/item/stealthy_weapons/cigarette_kit
name = "Cigarette Kit"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/cigarette
/datum/uplink_item/item/stealthy_weapons/random_toxin
name = "Random Toxin - Beaker"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/toxin

View File

@@ -0,0 +1,38 @@
/***************
* Telecrystals *
***************/
/datum/uplink_item/item/telecrystal
category = /datum/uplink_category/telecrystals
/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc)
return new /obj/item/stack/telecrystal(loc, cost(U.uses))
/datum/uplink_item/item/telecrystal/one
name = "Telecrystal - 01"
item_cost = 1
/datum/uplink_item/item/telecrystal/five
name = "Telecrystals - 05"
item_cost = 5
/datum/uplink_item/item/telecrystal/ten
name = "Telecrystals - 10"
item_cost = 10
/datum/uplink_item/item/telecrystal/twentyfive
name = "Telecrystals - 25"
item_cost = 25
/datum/uplink_item/item/telecrystal/fifty
name = "Telecrystals - 50"
item_cost = 50
/datum/uplink_item/item/telecrystal/onehundred
name = "Telecrystals - 100"
item_cost = 100
/datum/uplink_item/item/telecrystal/all
name = "Telecrystals - Empty Uplink"
/datum/uplink_item/item/telecrystal/all/cost(var/telecrystals)
return max(1, telecrystals)

View File

@@ -6,80 +6,74 @@
/datum/uplink_item/item/tools/toolbox
name = "Fully Loaded Toolbox"
item_cost = 1
item_cost = 10
path = /obj/item/weapon/storage/toolbox/syndicate
/datum/uplink_item/item/tools/plastique
name = "C-4 (Destroys walls)"
item_cost = 2
item_cost = 20
path = /obj/item/weapon/plastique
/datum/uplink_item/item/tools/encryptionkey_radio
name = "Encrypted Radio Channel Key"
item_cost = 2
item_cost = 20
path = /obj/item/device/encryptionkey/syndicate
/datum/uplink_item/item/tools/hacking_tool
name = "Door Hacking Tool"
item_cost = 20
path = /obj/item/device/multitool/hacktool
desc = "Appears and functions as a standard multitool until the mode is toggled by applying a screwdriver appropriately. \
When in hacking mode this device will grant full access to any standard airlock within 20 to 40 seconds. \
This device will also be able to immediately access the last 6 to 8 hacked airlocks."
/datum/uplink_item/item/tools/encryptionkey_binary
name = "Binary Translator Key"
item_cost = 3
item_cost = 30
path = /obj/item/device/encryptionkey/binary
/datum/uplink_item/item/tools/emag
name = "Cryptographic Sequencer"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/card/emag
/datum/uplink_item/item/tools/clerical
name = "Morphic Clerical Kit"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/clerical
/datum/uplink_item/item/tools/money
name = "Operations Funding"
item_cost = 30
path = /obj/item/weapon/storage/secure/briefcase/money
desc = "A briefcase with 10,000 untraceable thalers for funding your sneaky activities."
/datum/uplink_item/item/tools/space_suit
name = "Space Suit"
item_cost = 3
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/space
/datum/uplink_item/item/tools/thermal
name = "Thermal Imaging Glasses"
item_cost = 3
item_cost = 30
path = /obj/item/clothing/glasses/thermal/syndi
/datum/uplink_item/item/tools/powersink
name = "Powersink (DANGER!)"
item_cost = 5
item_cost = 50
path = /obj/item/device/powersink
/datum/uplink_item/item/tools/ai_module
name = "Hacked AI Upload Module"
item_cost = 7
item_cost = 70
path = /obj/item/weapon/aiModule/syndicate
/datum/uplink_item/item/tools/supply_beacon
name = "Hacked Supply Beacon (DANGER!)"
item_cost = 7
item_cost = 70
path = /obj/item/supply_beacon
/datum/uplink_item/item/tools/teleporter
name = "Teleporter Circuit Board"
item_cost = 20
path = /obj/item/weapon/circuitboard/teleporter
/datum/uplink_item/item/tools/money
name = "Operations Funding"
item_cost = 3
path = /obj/item/weapon/storage/secure/briefcase/money
desc = "A briefcase with 10,000 untraceable thalers for funding your sneaky activities."
/datum/uplink_item/item/tools/crystal
name = "Tradable Crystal"
item_cost = 1
path = /obj/item/device/telecrystal
desc = "A telecrystal that can be transferred from one user to another. Be sure not to give it to just anyone."
/datum/uplink_item/item/tools/hacking_tool
name = "Door Hacking Tool"
item_cost = 2
path = /obj/item/device/multitool/hacktool
desc = "Appears and functions as a standard multitool until the mode is toggled by applying a screwdriver appropriately. \
When in hacking mode this device will grant full access to any standard airlock within 20 to 40 seconds. \
This device will also be able to immediately access the last 6 to 8 hacked airlocks."
item_cost = 200
path = /obj/item/weapon/circuitboard/teleporter

View File

@@ -46,4 +46,7 @@ datum/uplink_category/ammunition
name = "Devices and Tools"
/datum/uplink_category/visible_weapons
name = "Highly Visible and Dangerous Weapons"
name = "Highly Visible and Dangerous Weapons"
/datum/uplink_category/telecrystals
name = "Telecrystals"

View File

@@ -4,39 +4,49 @@
/datum/uplink_item/item/visible_weapons
category = /datum/uplink_category/visible_weapons
/datum/uplink_item/item/visible_weapons/tactknife
name = "Tactical Knife"
item_cost = 10
path = /obj/item/weapon/material/hatchet/tacknife
/datum/uplink_item/item/visible_weapons/combatknife
name = "Combat Knife"
item_cost = 30
path = /obj/item/weapon/material/hatchet/tacknife/combatknife
/datum/uplink_item/item/visible_weapons/energy_sword
name = "Energy Sword"
item_cost = 4
item_cost = 40
path = /obj/item/weapon/melee/energy/sword
/datum/uplink_item/item/visible_weapons/dartgun
name = "Dart Gun"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/projectile/dartgun
/datum/uplink_item/item/visible_weapons/crossbow
name = "Energy Crossbow"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/energy/crossbow
/datum/uplink_item/item/visible_weapons/silenced_45
name = "Silenced .45"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/projectile/silenced
/datum/uplink_item/item/visible_weapons/riggedlaser
name = "Exosuit Rigged Laser"
item_cost = 6
item_cost = 60
path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser
/datum/uplink_item/item/visible_weapons/revolver
name = "Revolver"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/gun/projectile/revolver
/datum/uplink_item/item/visible_weapons/Derringer
name = ".357 Derringer Pistol"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/projectile/derringer
/datum/uplink_item/item/visible_weapons/heavysniper
@@ -46,18 +56,18 @@
/datum/uplink_item/item/visible_weapons/tommygun
name = "Tommygun (.45)" // We're keeping this because it's CLASSY. -Spades
item_cost = 7
item_cost = 70
path = /obj/item/weapon/gun/projectile/automatic/tommygun
//These are for traitors (or other antags, perhaps) to have the option of purchasing some merc gear.
/datum/uplink_item/item/visible_weapons/submachinegun
name = "Submachine Gun (10mm)"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/gun/projectile/automatic/c20r
/datum/uplink_item/item/visible_weapons/assaultrifle
name = "Assault Rifle (7.62mm)"
item_cost = 7
item_cost = 70
path = /obj/item/weapon/gun/projectile/automatic/sts35
/*/datum/uplink_item/item/visible_weapons/bullpuprifle
@@ -67,40 +77,30 @@
*/
/datum/uplink_item/item/visible_weapons/combatshotgun
name = "Combat Shotgun"
item_cost = 7
item_cost = 70
path = /obj/item/weapon/gun/projectile/shotgun/pump/combat
/datum/uplink_item/item/visible_weapons/egun
name = "Energy Gun"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/energy/gun
/datum/uplink_item/item/visible_weapons/lasercannon
name = "Laser Cannon"
item_cost = 6
item_cost = 60
path = /obj/item/weapon/gun/energy/lasercannon
/datum/uplink_item/item/visible_weapons/lasercarbine
name = "Laser Carbine"
item_cost = 7
item_cost = 70
path = /obj/item/weapon/gun/energy/laser
/datum/uplink_item/item/visible_weapons/ionrifle
name = "Ion Rifle"
item_cost = 5
item_cost = 50
path = /obj/item/weapon/gun/energy/ionrifle
/datum/uplink_item/item/visible_weapons/xray
name = "Xray Gun"
item_cost = 7
path = /obj/item/weapon/gun/energy/xray
/datum/uplink_item/item/visible_weapons/tactknife
name = "Tactical Knife"
item_cost = 1
path = /obj/item/weapon/material/hatchet/tacknife
/datum/uplink_item/item/visible_weapons/combatknife
name = "Combat Knife"
item_cost = 3
path = /obj/item/weapon/material/hatchet/tacknife/combatknife
item_cost = 70
path = /obj/item/weapon/gun/energy/xray

View File

@@ -0,0 +1,19 @@
/datum/technomancer/equipment/boots_of_speed
name = "Boots of Speed"
desc = "What appears to be an ordinary pair of boots, is actually a bit more useful than that. These will help against slipping \
on flat surfaces, and will make you run a bit faster than if you had normal shoes or boots on."
cost = 50
obj_path = /obj/item/clothing/shoes/speed
/obj/item/clothing/shoes/speed
name = "boots of speed"
desc = "The latest in sure footing technology."
icon_state = "swat"
item_flags = NOSLIP
siemens_coefficient = 0.6
slowdown = -2 // A bit faster than normal shows.
cold_protection = FEET
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = FEET
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE

View File

@@ -31,7 +31,8 @@
user << "<span class='danger'>\The [src] has ran out of uses, and is now useless to you!</span>"
return
else
var/area/A = input(user, "Area to teleport to", "Teleportation") in teleportlocs
var/area_wanted = input(user, "Area to teleport to", "Teleportation") in teleportlocs
var/area/A = teleportlocs[area_wanted]
if(!A)
return
@@ -62,8 +63,8 @@
targets.Add(T)
if(!targets.len)
user <<"The teleporter matrix was unable to locate a suitable teleport destination, as all the possibilities were nonexistant \
or hazardous. Try a different area."
user << "The teleporter matrix was unable to locate a suitable teleport destination, as all the possibilities \
were nonexistant or hazardous. Try a different area."
return
var/turf/simulated/destination = null

View File

@@ -0,0 +1,67 @@
/datum/technomancer/equipment/gloves_of_regen
name = "Gloves of Regeneration"
desc = "It's a pair of black gloves, with a hypodermic needle on the insides, and a small storage of a secret blend of chemicals \
designed to be slowly fed into a living person's system, increasing their metabolism greatly, resulting in accelerated healing. \
A side effect of this healing is that the wearer will generally get hungry a lot faster. Sliding the gloves on and off also \
hurts a lot. As a bonus, the gloves are more resistant to the elements than most. It should be noted that synthetics will have \
little use for these."
cost = 50
obj_path = /obj/item/clothing/gloves/regen
/obj/item/clothing/gloves/regen
name = "gloves of regeneration"
desc = "A pair of gloves with a small storage of green liquid on the outside. On the inside, a a hypodermic needle can be seen \
on each glove."
icon_state = "regen"
item_state = "graygloves"
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE
var/mob/living/carbon/human/wearer = null
/obj/item/clothing/gloves/regen/equipped(var/mob/living/carbon/human/H)
if(H && H.gloves == src)
wearer = H
if(wearer.can_feel_pain())
H << "<span class='danger'>You feel a stabbing sensation in your hands as you slide \the [src] on!</span>"
wearer.custom_pain("You feel a sharp pain in your hands!",1)
..()
/obj/item/clothing/gloves/regen/dropped(var/mob/living/carbon/human/H)
..()
if(wearer)
if(wearer.can_feel_pain())
wearer << "<span class='danger'>You feel the hypodermic needles as you slide \the [src] off!</span>"
wearer.custom_pain("Your hands hurt like hell!",1)
wearer = null
/obj/item/clothing/gloves/regen/New()
processing_objects |= src
..()
/obj/item/clothing/gloves/regen/Destroy()
wearer = null
processing_objects -= src
..()
/obj/item/clothing/gloves/regen/process()
if(!wearer || wearer.isSynthetic() || wearer.stat == DEAD || wearer.nutrition >= 10)
return // Robots and dead people don't have a metabolism.
if(wearer.getBruteLoss())
wearer.adjustBruteLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getFireLoss())
wearer.adjustFireLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getToxLoss())
wearer.adjustToxLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getOxyLoss())
wearer.adjustOxyLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getCloneLoss())
wearer.adjustCloneLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 20, 0)

View File

@@ -71,12 +71,54 @@
new /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat(src)
..()
/datum/technomancer/equipment/belt_of_holding
name = "Belt of Holding"
desc = "A belt with a literal pocket which opens to a localized pocket of 'Blue-Space', allowing for more storage. \
The nature of the pocket allows for storage of larger objects than what is typical for other belts, and in larger quanities. \
It will also help keep your pants on."
cost = 100
obj_path = /obj/item/weapon/storage/belt/holding
/obj/item/weapon/storage/belt/holding
name = "Belt of Holding"
desc = "Can hold more than you'd expect."
icon_state = "emsbelt"
item_state = "emsbelt"
max_w_class = 3 // Can hold normal sized items.
storage_slots = 14 // Twice the capacity of a typical belt.
max_storage_space = 42
/datum/technomancer/equipment/thermals
name = "Thermoncle"
desc = "A fancy monocle with a thermal optics lens installed. Allows you to see people across walls."
cost = 150
obj_path = /obj/item/clothing/glasses/thermal/plain/monocle
/datum/technomancer/equipment/night_vision
name = "Night Vision Goggles"
desc = "Strategical goggles which will allow the wearer to see in the dark. Perfect for the sneaky type, just get rid of the \
lights first."
cost = 50
obj_path = /obj/item/clothing/glasses/night
/datum/technomancer/equipment/omni_sight
name = "Omnisight Scanner"
desc = "A very rare scanner worn on the face, which allows the wearer to see nearly anything across walls."
cost = 400
obj_path = /obj/item/clothing/glasses/omni
/obj/item/clothing/glasses/omni
name = "Omnisight Scanner"
desc = "A pair of goggles which, while on the surface appear to be build very poorly, reveal to be very advanced in \
capabilities. The lens appear to be multiple optical matrices layered together, allowing the wearer to see almost anything \
across physical barriers."
icon_state = "uzenwa_sissra_1"
action_button_name = "Toggle Goggles"
origin_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6)
toggleable = 1
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
prescription = 1 // So two versions of these aren't needed.
/datum/technomancer/equipment/med_hud
name = "Medical HUD"
desc = "A commonly available HUD for medical professionals, which displays how healthy an individual is. \
@@ -84,7 +126,6 @@
cost = 30
obj_path = /obj/item/clothing/glasses/thermal/plain/monocle
/datum/technomancer/equipment/scepter
name = "Scepter of Empowerment"
desc = "A gem sometimes found in the depths of asteroids makes up the basis for this device. Energy is channeled into it from \
@@ -112,4 +153,4 @@
var/obj/item/item_to_test = user.get_other_hand(src)
if(istype(item_to_test, /obj/item/weapon/spell))
var/obj/item/weapon/spell/S = item_to_test
S.on_scepter_ranged_cast(target, user)
S.on_scepter_ranged_cast(target, user)

View File

@@ -44,26 +44,26 @@
// Description: Makes instability decay. instability_effects() handles the bad effects for having instability. It will also hold back
// from causing bad effects more than one every ten seconds, to prevent sudden death from angry RNG.
/mob/living/carbon/human/proc/handle_instability()
instability = Clamp(instability, 0, 200)
instability = round(Clamp(instability, 0, 200))
instability_update_hud()
//This should cushon against really bad luck.
if(instability && last_instability_event < (world.time - 10 SECONDS) && prob(20))
instability_effects()
switch(instability)
if(1 to 10)
adjust_instability(-1)
if(11 to 20)
adjust_instability(-2)
if(21 to 30)
adjust_instability(-3)
if(31 to 40)
if(11 to 20)
adjust_instability(-4)
if(21 to 30)
adjust_instability(-6)
if(31 to 40)
adjust_instability(-8)
if(41 to 50)
adjust_instability(-5)
if(51 to 100)
adjust_instability(-10)
if(101 to 200)
if(51 to 100)
adjust_instability(-20)
if(101 to 200)
adjust_instability(-40)
/*
[16:18:08] <PsiOmegaDelta> Sparks
@@ -88,6 +88,7 @@
sleep(4)
overlays.Remove(instability_flash)
qdel(instability_flash)
radiate_instability()
switch(instability)
if(1 to 10) //Harmless
return
@@ -165,6 +166,7 @@
src << "<span class='danger'>You feel your body slowly degenerate.</span>"
if(7)
adjustToxLoss(instability * 0.25) //25 tox @ 100 instability
if(101 to 200) //Lethal
rng = rand(0,8)
switch(rng)
@@ -191,3 +193,18 @@
src << "<span class='danger'>You feel your body slowly degenerate.</span>"
if(7)
adjustToxLoss(instability * 0.40) //25 tox @ 100 instability
/mob/living/carbon/human/proc/radiate_instability()
var/distance = round(sqrt(instability / 2))
if(instability <= 30)
distance = 0
if(distance)
for(var/mob/living/carbon/human/H in range(src, distance) )
if(H == src) // This instability is radiating away from them, so don't include them.
continue
var/radius = max(get_dist(H, src), 1)
// People next to the source take a third of the instability. Further distance decreases the amount absorbed.
var/outgoing_instability = (instability / 3) * ( 1 / (radius**2) )
H.adjust_instability(outgoing_instability)
set_light(distance, distance, l_color = "#C26DDE")

View File

@@ -23,4 +23,20 @@
/obj/item/weapon/spell/proc/allowed_to_teleport()
if(owner && owner.z in config.admin_levels)
return 0
return 1
return 1
// Returns a 'target' mob from a radius around T.
/obj/item/weapon/spell/proc/targeting_assist(var/turf/T, radius = 5)
var/chosen_target = null
var/potential_targets = view(T,radius)
for(var/mob/living/L in potential_targets)
if(is_ally(L)) // Don't shoot our friends.
continue
if(L.invisibility > owner.see_invisible) // Don't target ourselves or people we can't see.
continue
if(!L in viewers(owner)) // So we don't shoot at walls if someone is hiding behind one.
continue
if(!L.stat) // Don't want to target dead people or SSDs.
chosen_target = L
break
return chosen_target

View File

@@ -31,10 +31,20 @@
"Flash" = 'sound/weapons/flash.ogg',
"Bite" = 'sound/weapons/bite.ogg',
"Gun Firing" = 'sound/weapons/gunshot.ogg',
"Desert Eagle Firing" = 'sound/weapons/deagle.ogg',
"Rifle Firing" = 'sound/weapons/rifleshot.ogg',
"Rifle Firing 2" = 'sound/weapons/svd_shot.ogg',
"Sniper Firing" = 'sound/weapons/sniper.ogg',
"Shotgun Firing" = 'sound/weapons/shotgun.ogg',
"Semi-automatic Firing" = 'sound/weapons/semiauto.ogg',
"Machinegun Firing" = 'sound/weapons/machinegun.ogg',
"Rocket Launcher Firing"= 'sound/weapons/rpg.ogg',
"Taser Firing" = 'sound/weapons/Taser.ogg',
"Laser Gun Firing" = 'sound/weapons/laser.ogg',
"E-Luger Firing" = 'sound/weapons/eLuger.ogg',
"Xray Gun Firing" = 'sound/weapons/laser3.ogg',
"Pulse Gun Firing" = 'sound/weapons/pulse.ogg',
"Gauss Gun Firing" = 'sound/weapons/gauss_shoot.ogg',
"Emitter Firing" = 'sound/weapons/emitter.ogg',
"Energy Blade On" = 'sound/weapons/saberon.ogg',
"Energy Blade Off" = 'sound/weapons/saberoff.ogg',

View File

@@ -0,0 +1,29 @@
/datum/technomancer/spell/gambit
name = "Gambit"
desc = "This function causes you to receive a random function, including those which you haven't purchased."
ability_icon_state = "tech_gambit"
cost = 50
obj_path = /obj/item/weapon/spell/gambit
/var/global/list/all_technomancer_gambit_spells = typesof(/obj/item/weapon/spell) - list(
/obj/item/weapon/spell/gambit,
/obj/item/weapon/spell/projectile,
/obj/item/weapon/spell/aura,
/obj/item/weapon/spell/insert,
/obj/item/weapon/spell/spawner)
/obj/item/weapon/spell/gambit
name = "gambit"
desc = "Do you feel lucky?"
icon_state = "gambit"
cast_methods = CAST_USE
aspect = ASPECT_UNSTABLE
/obj/item/weapon/spell/gambit/on_use_cast(mob/living/carbon/human/user)
if(pay_energy(200))
adjust_instability(3)
var/obj/item/weapon/spell/random_spell = pick(all_technomancer_gambit_spells)
if(random_spell)
user.drop_from_inventory(src, null)
user.place_spell_in_hand(random_spell)
qdel(src)

View File

@@ -26,6 +26,9 @@
aspect = ASPECT_TELE
/obj/item/weapon/spell/mark/on_use_cast(mob/living/user)
if(!allowed_to_teleport()) // Otherwise you could teleport back to the admin Z-level.
user << "<span class='warning'>You can't teleport here!</span>"
return 0
if(pay_energy(1000))
if(!mark_spell_ref)
mark_spell_ref = new(get_turf(user))
@@ -77,8 +80,23 @@
set_light(light_intensity, light_intensity, l_color = "#006AFF")
time_left--
sleep(1 SECOND)
user.forceMove(get_turf(mark_spell_ref))
var/turf/target_turf = get_turf(mark_spell_ref)
var/turf/old_turf = get_turf(user)
for(var/obj/item/weapon/grab/G in user.contents) // People the Technomancer is grabbing come along for the ride.
if(G.affecting)
G.affecting.forceMove(locate( target_turf.x+rand(-1,1), target_turf.y+rand(-1,1), target_turf.z))
G.affecting << "<span class='warning'>You are teleported along with [user]!</span>"
user.forceMove(target_turf)
user << "<span class='notice'>You are teleported to your Mark.</span>"
playsound(target_turf, 'sound/effects/phasein.ogg', 25, 1)
playsound(target_turf, 'sound/effects/sparks2.ogg', 50, 1)
playsound(old_turf, 'sound/effects/sparks2.ogg', 50, 1)
owner.adjust_instability(25)
qdel(src)
return 1

View File

@@ -2,6 +2,7 @@
name = "Beam"
desc = "Fires a laser at your target. Cheap, reliable, and a bit boring."
cost = 150
ability_icon_state = "tech_beam"
obj_path = /obj/item/weapon/spell/projectile/beam
/obj/item/weapon/spell/projectile/beam

View File

@@ -51,5 +51,6 @@
user.visible_message("<span class='danger'>\The [user]'s [src] blocks [attack_text]!</span>")
spark_system.start()
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
adjust_instability(2)
return 1
return 0

View File

@@ -0,0 +1,35 @@
/datum/technomancer/spell/targeting_matrix
name = "Targeting Matrix"
desc = "Automatically targets and fires a ranged weapon or function at a non-friendly target near a targeted tile. \
Each target assisted attack costs some energy and instability."
cost = 150
ability_icon_state = "tech_targetingmatrix"
obj_path = /obj/item/weapon/spell/targeting_matrix
/obj/item/weapon/spell/targeting_matrix
name = "targeting matrix"
desc = "Aiming is too much effort for you."
icon_state = "targeting_matrix"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE //idk?
/obj/item/weapon/spell/targeting_matrix/on_ranged_cast(atom/hit_atom, mob/user)
var/turf/T = get_turf(hit_atom)
if(T)
var/mob/living/chosen_target = targeting_assist(T,5) //The person who's about to get attacked.
if(!chosen_target)
return 0
var/obj/item/I = user.get_inactive_hand()
if(I && pay_energy(200))
var/prox = user.Adjacent(chosen_target)
if(prox) // Needed or else they can attack with melee from afar.
I.attack(chosen_target,owner)
I.afterattack(chosen_target,owner, prox)
adjust_instability(2)
var/image/target_image = image(icon = 'icons/obj/spells.dmi', loc = get_turf(chosen_target), icon_state = "target")
user << target_image
sleep(5)
qdel(target_image)

View File

@@ -0,0 +1,74 @@
/datum/technomancer/spell/track
name = "Track"
desc = "Acts as directional guidance towards an object that belongs to you or your team. It can also point towards your allies. \
Wonderful if you're worried someone will steal your valuables, like a certain shiny Scepter..."
enhancement_desc = "You will be able to track most other entities in addition to your belongings and allies."
cost = 30
obj_path = /obj/item/weapon/spell/track
ability_icon_state = "tech_track"
// This stores a ref to all important items that belong to a Technomancer, in case of theft. Used by the spell below.
// I feel dirty for adding yet another global list used by one thing, but the only alternative is to loop through world, and yeahhh.
var/list/technomancer_belongings = list()
/obj/item/weapon/spell/track
name = "track"
icon_state = "track"
desc = "Never lose your stuff again!"
cast_methods = CAST_USE
aspect = ASPECT_TELE
var/atom/movable/tracked = null // The thing to point towards.
var/tracking = 0 // If one, points towards tracked.
/obj/item/weapon/spell/track/Destroy()
tracked = null
tracking = 0
/obj/item/weapon/spell/track/on_use_cast(mob/user)
if(tracking)
tracking = 0
user << "<span class='notice'>You stop tracking for \the [tracked]'s whereabouts.</span>"
tracked = null
return
var/can_track_non_allies = 0
var/list/object_choices = technomancer_belongings.Copy()
if(check_for_scepter())
can_track_non_allies = 1
var/list/mob_choices = list()
for(var/mob/living/L in mob_list)
if(!is_ally(L) && !can_track_non_allies)
continue
mob_choices += L
var/choice = input(user,"Decide what or who to track.","Tracking") as null|anything in object_choices + mob_choices
if(choice)
tracked = choice
tracking = 1
track()
/obj/item/weapon/spell/track/proc/track()
if(!tracking)
icon_state = "track"
return
if(!tracked)
icon_state = "track_unknown"
if(tracked.z != owner.z)
icon_state = "track_unknown"
else
set_dir(get_dir(src,tracked))
switch(get_dist(src,tracked))
if(0)
icon_state = "track_direct"
if(1 to 8)
icon_state = "track_close"
if(9 to 16)
icon_state = "track_medium"
if(16 to INFINITY)
icon_state = "track_far"
spawn(5)
.()

View File

@@ -3,11 +3,12 @@
desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object."
cost = 200
obj_path = /obj/item/weapon/spell/warp_strike
ability_icon_state = "tech_warpstrike"
/obj/item/weapon/spell/warp_strike
name = "warp strike"
desc = "The answer to the problem of bringing a knife to a gun fight."
icon_state = "tech_warpstrike"
icon_state = "warp_strike"
cast_methods = CAST_RANGED
aspect = ASPECT_TELE
var/datum/effect/effect/system/spark_spread/sparks
@@ -23,16 +24,7 @@
if(T)
//First, we handle who to teleport to.
user.setClickCooldown(5)
var/list/potential_targets = view(T, 2) //Everyone in a 5x5 range of the tile we clicked on.
var/mob/living/chosen_target = null //The person who's about to get attacked.
//Find us someone to robust.
for(var/mob/living/L in potential_targets)
if(L == user || L.invisibility > user.see_invisible) //Don't target ourselves or people we can't see.
continue
if(!L.stat) //Don't want to target dead people or SSDs.
chosen_target = L
break
var/mob/living/chosen_target = targeting_assist(T,5) //The person who's about to get attacked.
if(!chosen_target)
return 0
@@ -60,7 +52,12 @@
//Finally, we handle striking the victim with whatever's in the user's offhand.
var/obj/item/I = user.get_inactive_hand()
var/list/blacklisted_items = list(/obj/item/weapon/gun) //We don't want these items to be used, likely because it would break balance.
// List of items we don't want used, for balance reasons or to avoid infinite loops.
var/list/blacklisted_items = list(
/obj/item/weapon/gun,
/obj/item/weapon/spell/warp_strike,
/obj/item/weapon/spell/targeting_matrix
)
if(I)
if(is_path_in_list(I.type, blacklisted_items))

View File

@@ -109,9 +109,9 @@
dat += "<A href='?src=\ref[src];action=create;item=milk;cost=20'>10 milk</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT><BR>"
dat += "<A href='?src=\ref[src];action=create;item=meat;cost=50'>Slab of meat</A> <FONT COLOR=blue>([round(50/build_eff)])</FONT><BR>"
dat += "Nutrient<BR>"
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=60'>E-Z-Nutrient</A> <FONT COLOR=blue>([round(10/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=300'>x5</A><BR>"
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=120'>Left 4 Zed</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=600'>x5</A><BR>"
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=150'>Robust Harvest</A> <FONT COLOR=blue>([round(25/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=750'>x5</A><BR>"
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=60'>E-Z-Nutrient</A> <FONT COLOR=blue>([round(60/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=300'>x5</A><BR>"
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=120'>Left 4 Zed</A> <FONT COLOR=blue>([round(120/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=600'>x5</A><BR>"
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=150'>Robust Harvest</A> <FONT COLOR=blue>([round(150/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=750'>x5</A><BR>"
dat += "Leather<BR>"
dat += "<A href='?src=\ref[src];action=create;item=wallet;cost=100'>Wallet</A> <FONT COLOR=blue>([round(100/build_eff)])</FONT><BR>"
dat += "<A href='?src=\ref[src];action=create;item=gloves;cost=250'>Botanical gloves</A> <FONT COLOR=blue>([round(250/build_eff)])</FONT><BR>"

View File

@@ -222,6 +222,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/mob/observer/dead
var/datum/exonet_protocol/exonet = null
var/list/exonet_messages = list()
// Proc: New()
// Parameters: None
@@ -305,6 +306,10 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(comm.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
for(var/mob/observer/dead/ghost in im_contacts)
if(ghost.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
//Actual messages.
for(var/I in im_list)
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
@@ -411,6 +416,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("[usr] (COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]")
if(href_list["disconnect"])
var/name_to_disconnect = href_list["disconnect"]
@@ -493,7 +499,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Proc: receive_exonet_message()
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message)
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
if(message == "voice")
if(istype(origin_atom, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = origin_atom
@@ -508,7 +514,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
var/random = rand(450,700)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text") //Ghosts don't get texting yet. Mostly for spam prevention by ghosts but also due to ui requirements not sorted out yet.
if(message == "text")
src << "<span class='notice'>\icon[origin_atom] Received text message from [origin_atom]: <b>\"[text]\"</b></span>"
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
// Proc: register_device()
@@ -533,7 +541,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
communicating |= comm
listening_objects |= src
update_icon()
// Proc: del_communicating()
// Parameters: 1 (comm - the communicator to remove from communicating)
// Description: Used when this communicator is being asked to stop relaying say/me messages to another
@@ -732,7 +740,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
var/who = null
if(isobserver(candidate))
return
var/mob/observer/dead/ghost = candidate
who = ghost
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
@@ -811,7 +821,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(!T) return
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display
var/list/mobs_to_relay = in_range["mobs"]
for(var/mob/mob in mobs_to_relay) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other.
var/dst = get_dist(get_turf(mob),get_turf(comm))
if(dst <= video_range)
@@ -827,7 +837,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Description: Relays the speech to all linked communicators.
/obj/item/device/communicator/hear_talk(mob/living/M, text, verb, datum/language/speaking)
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0)
@@ -915,6 +925,71 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
src << "A communications request has been sent to [chosen_communicator]. Now you need to wait until someone answers."
// Verb: text_communicator()
// Parameters: None
// Description: Allows a ghost to send a text message to a communicator.
/mob/observer/dead/verb/text_communicator()
set category = "Ghost"
set name = "Text Communicator"
set desc = "If there is a communicator available, send a text message to it."
if(ticker.current_state < GAME_STATE_PLAYING)
src << "<span class='danger'>The game hasn't started yet!</span>"
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
src << "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>"
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
src << "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, so your call can't go through.</span>"
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
src << "<span class='danger'>There are no available communicators, sorry.</span>"
return
var/choice = input(src,"Send a text message to whom?") as null|anything in choices
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(input(src, "What do you want the message to say?")) as message
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
src << "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>."
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
log_pda("[usr] (COMM: [src]) sent \"[text_message]\" to [chosen_communicator]")
// Verb: show_text_messages()
// Parameters: None
// Description: Lets ghosts review messages they've sent or received.
/mob/observer/dead/verb/show_text_messages()
set category = "Ghost"
set name = "Show Text Messages"
set desc = "Allows you to see exonet text messages you've sent and received."
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
for(var/line in exonet_messages)
HTML += line + "<br>"
HTML +="</body></html>"
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
// Proc: connect_video()
// Parameters: user - the mob doing the viewing of video, comm - the communicator at the far end
// Description: Sets up a videocall and puts the first view into it using watch_video, and updates the icon
@@ -963,7 +1038,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Description: Cleans up mob's client when they stop watching a video
/obj/item/device/communicator/proc/video_cleanup(mob/user)
if(!user) return
user.reset_view(null)
user.unset_machine()
@@ -972,14 +1047,14 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
video_source = null
. = "<span class='danger'>\icon[src] [reason ? reason : "Video session ended"].</span>"
visible_message(.)
update_icon()
//For synths who have no hands.
/obj/item/device/communicator/integrated
/obj/item/device/communicator/integrated
name = "integrated communicator"
desc = "A circuit used for long-range communications, able to be integrated into a system."

View File

@@ -1,20 +0,0 @@
/*
Telecrystal item
Does nothing if not suitable antag type, checks for accept_tcrystals = 1 in a mob's mind.
For new antags, make sure to add "player.mind.accept_tcrystals = 1" if you want tradable tcrystals.
*/
/obj/item/device/telecrystal
name = "red crystal"
desc = "A strange, red, glowing crystal."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "telecrystal"
force = 5
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 1, TECH_ILLEGAL = 1)
/obj/item/device/telecrystal/attack_self(mob/user as mob)
if(user.mind.accept_tcrystals) //Checks to see if antag type allows for tcrystals
user.mind.tcrystals += 1
user.drop_from_inventory(src)
qdel(src)
return

View File

@@ -0,0 +1,29 @@
/obj/item/stack/telecrystal
name = "telecrystal"
desc = "It seems to be pulsing with suspiciously enticing energies."
description_antag = "Telecrystals can be activated by utilizing them on devices with an actively running uplink. They will not activate on unactivated uplinks."
singular_name = "telecrystal"
icon = 'icons/obj/stock_parts.dmi'
icon_state = "telecrystal"
w_class = 1
max_amount = 240
flags = NOBLUDGEON
origin_tech = list(TECH_MATERIAL = 6, TECH_BLUESPACE = 4)
/obj/item/stack/telecrystal/afterattack(var/obj/item/I as obj, mob/user as mob, proximity)
if(!proximity)
return
if(istype(I, /obj/item))
if(I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
I.hidden_uplink.uses += amount
I.hidden_uplink.update_nano_data()
nanomanager.update_uis(I.hidden_uplink)
use(amount)
user << "<span class='notice'>You slot \the [src] into \the [I] and charge its internal uplink.</span>"
/obj/item/stack/telecrystal/attack_self(mob/user as mob)
if(user.mind.accept_tcrystals) //Checks to see if antag type allows for tcrystals
user << "<span class='notice'>You use \the [src], adding [src.amount] to your balance.</span>"
user.mind.tcrystals += amount
use(amount)
return

View File

@@ -69,7 +69,6 @@
icon_state = "emag"
item_state = "card-id"
origin_tech = list(TECH_MAGNET = 2, TECH_ILLEGAL = 2)
var/default_uses = 10
var/uses = 10
/obj/item/weapon/card/emag/resolve_attackby(atom/A, mob/user)
@@ -89,9 +88,15 @@
qdel(src)
return 1
/obj/item/weapon/card/emag/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/device/telecrystal))
src.uses += default_uses/2 //Adds half the default amount of uses which is more than you get per TC when buying, as to balance the utility of having multiple emags vs one heavily usable one
if(istype(O, /obj/item/stack/telecrystal))
var/obj/item/stack/telecrystal/T = O
if(T.amount < 1)
usr << "<span class='notice'>You are not adding enough telecrystals to fuel \the [src].</span>"
return
uses += T.amount/2 //Gives 5 uses per 10 TC
uses = ceil(uses) //Ensures no decimal uses nonsense, rounds up to be nice
usr << "<span class='notice'>You add \the [O] to \the [src]. Increasing the uses of \the [src] to [uses].</span>"
qdel(O)

View File

@@ -38,6 +38,22 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "unathiknife"
attack_verb = list("ripped", "torn", "cut")
var hits = 0
/obj/item/weapon/material/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob)
if(hits > 0)
return
var/obj/item/I = user.get_inactive_hand()
if(istype(I, /obj/item/weapon/material/hatchet/unathiknife))
hits ++
var/obj/item/weapon/W = I
W.attack(M, user)
W.afterattack(M, user)
..()
/obj/item/weapon/material/hatchet/unathiknife/afterattack(mob/M as mob, mob/user as mob)
hits = initial(hits)
..()
/obj/item/weapon/material/hatchet/tacknife
name = "tactical knife"

View File

@@ -1,8 +1,8 @@
/world
hub = "Exadv1.spacestation13"
hub_password = "SORRYNOPASSWORD"
//hub_password = "kMZy3U5jJHSiBQjr"
//hub_password = "SORRYNOPASSWORD"
hub_password = "kMZy3U5jJHSiBQjr"
name = "Space Station 13"
/* This is for any host that would like their server to appear on the main SS13 hub.

View File

@@ -287,6 +287,7 @@
'html/panels.css',
'html/images/loading.gif',
'html/images/ntlogo.png',
'html/images/sglogo.png',
'html/images/talisman.png',
'icons/pda_icons/pda_atmos.png',
'icons/pda_icons/pda_back.png',

View File

@@ -31,6 +31,21 @@
path = /obj/item/clothing/head/beret/sec/navy/hos
allowed_roles = list("Head of Security")
/datum/gear/head/beret/csec
display_name = "beret, corporate (officer)"
path = /obj/item/clothing/head/beret/sec/corporate/officer
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/head/beret/csec_warden
display_name = "beret, corporate (warden)"
path = /obj/item/clothing/head/beret/sec/corporate/warden
allowed_roles = list("Head of Security","Warden")
/datum/gear/head/beret/csec_hos
display_name = "beret, corporate (hos)"
path = /obj/item/clothing/head/beret/sec/corporate/hos
allowed_roles = list("Head of Security")
/datum/gear/head/beret/eng
display_name = "beret, engie-orange"
path = /obj/item/clothing/head/beret/engineering

View File

@@ -283,4 +283,8 @@
/datum/gear/suit/flannel/aqua
display_name = "aqua flannel"
path = /obj/item/clothing/suit/storage/flannel/aqua
path = /obj/item/clothing/suit/storage/flannel/aqua
/datum/gear/suit/flannel/brown
display_name = "brown flannel"
path = /obj/item/clothing/suit/storage/flannel/brown

View File

@@ -704,6 +704,7 @@
icon_state += "t"
if(buttoned)
icon_state += "b"
update_clothing_icon()
/obj/item/clothing/suit/storage/flannel/red
desc = "A comfy, red flannel shirt. Unleash your inner hipster."
@@ -715,6 +716,11 @@
icon_state = "flannel_aqua"
item_state = "blue_labcoat"
/obj/item/clothing/suit/storage/flannel/brown
desc = "A comfy, brown flannel shirt. Unleash your inner hipster."
icon_state = "flannel_brown"
item_state = "johnny"
//Green Uniform
/obj/item/clothing/suit/storage/toggle/greengov

View File

@@ -1328,13 +1328,11 @@
var/obj/item/organ/external/current_limb = organs_by_name[limb]
if(current_limb && current_limb.dislocated > 0 && !current_limb.is_parent_dislocated()) //if the parent is also dislocated you will have to relocate that first
limbs |= current_limb
var/choice = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs
var/obj/item/organ/external/current_limb = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs
if(!choice)
if(!current_limb)
return
var/obj/item/organ/external/current_limb = organs_by_name[choice]
if(self)
src << "<span class='warning'>You brace yourself to relocate your [current_limb.joint]...</span>"
else
@@ -1342,7 +1340,7 @@
if(!do_after(U, 30))
return
if(!choice || !current_limb || !S || !U)
if(!current_limb || !S || !U)
return
if(self)

View File

@@ -18,9 +18,6 @@
ExtinguishMob()
return TRUE
if(..())
return TRUE
if(handcuffed)
spawn() escape_handcuffs()
else if(legcuffed)
@@ -59,8 +56,8 @@
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!handcuffed || buckled)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
if(!handcuffed)
return
visible_message(
"<span class='danger'>\The [src] manages to remove \the [handcuffed]!</span>",

View File

@@ -260,6 +260,7 @@
t = replacetext(t, "\[row\]", "</td><tr>")
t = replacetext(t, "\[cell\]", "<td>")
t = replacetext(t, "\[logo\]", "<img src = ntlogo.png>")
t = replacetext(t, "\[sglogo\]", "<img src = sglogo.png>")
t = "<font face=\"[deffont]\" color=[P ? P.colour : "black"]>[t]</font>"
else // If it is a crayon, and he still tries to use these, make them empty!
@@ -274,6 +275,7 @@
t = replacetext(t, "\[row\]", "")
t = replacetext(t, "\[cell\]", "")
t = replacetext(t, "\[logo\]", "")
t = replacetext(t, "\[sglogo\]", "")
t = "<font face=\"[crayonfont]\" color=[P ? P.colour : "black"]><b>[t]</b></font>"

View File

@@ -56,6 +56,10 @@
name = "quartermaster's stamp"
icon_state = "stamp-qm"
/obj/item/weapon/stamp/solgov
name = "solgov stamp"
icon_state = "stamp-sg"
// Syndicate stamp to forge documents.
/obj/item/weapon/stamp/chameleon/attack_self(mob/user as mob)

View File

@@ -636,25 +636,16 @@
if(alien == IS_DIONA)
return
..()
if(alien == IS_TAJARA)
M.adjustToxLoss(0.5 * removed)
M.make_jittery(4) //extra sensitive to caffine
if(adj_temp > 0)
holder.remove_reagent("frostoil", 10 * removed)
/datum/reagent/nutriment/coffee/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(alien == IS_TAJARA)
M.adjustToxLoss(2 * removed)
M.make_jittery(4)
return
/datum/reagent/drink/coffee/overdose(var/mob/living/carbon/M, var/alien)
if(alien == IS_DIONA)
return
if(alien == IS_TAJARA)
M.adjustToxLoss(4 * REM)
M.apply_effect(3, STUTTER)
M.make_jittery(5)
/datum/reagent/drink/coffee/icecoffee

View File

@@ -164,20 +164,14 @@
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(..())
var/obj/item/stack/cable_coil/C = tool
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth")
if(!limb_can_operate)
return 0
if(istype(C))
if(istype(tool,/obj/item/stack/cable_coil/))
var/obj/item/stack/cable_coil/C = tool
if(!C.can_use(10))
user << "<span class='danger'>You need ten or more cable pieces to repair this damage.</span>" //usage amount made more consistent with regular cable repair
return SURGERY_FAILURE
C.use(10)
return 1
return affected && affected.open == 3 && (affected.disfigured || affected.burn_dam > 0) && target_zone != O_MOUTH
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)