Merge pull request #9 from Duck-/master

Here's my stuffsfjfsflkj
This commit is contained in:
SoundScopes
2014-12-24 08:23:39 +00:00
23 changed files with 1190 additions and 49 deletions
+14
View File
@@ -256,6 +256,20 @@
var/verb = "says in a subdued tone"
..(message, verb)
verb/bstwalk()
set name = "Ruin Everything"
set desc = "Uses bluespace technology to phase through solid matter and also move fast."
set category = "BST"
set popup_menu = 0
if(!src.incorporeal_move)
src.incorporeal_move = 2
src << "\blue You will now phase through solid matter."
else
src.incorporeal_move = 0
src << "\blue You will no-longer phase through solid matter."
return
//Equipment. All should have canremove set to 0
//All items with a /bst need the attack_hand() proc overrided to stop people getting overpowered items.
+1 -1
View File
@@ -335,7 +335,7 @@ BLIND // can't see anything
permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
@@ -22,7 +22,7 @@
allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
slowdown = 1.5
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.7
@@ -478,10 +478,9 @@
var/obj/machinery/bot/mulebot/MB = AM
MB.RunOver(src)
/* if(istype(AM, /obj/vehicle))
if(istype(AM, /obj/vehicle))
var/obj/vehicle/V = AM
V.RunOver(src)
*/
//gets assignment from ID or ID inside PDA or PDA itself
//Useful when player do something with computers
+5 -1
View File
@@ -203,7 +203,8 @@
if(!mob.canmove)
return
if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair) || istype(mob.buckled, /obj/vehicle))) // Exception for wheelchairs
else return
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
// if(!mob.Process_Spacemove(0)) return 0
@@ -257,6 +258,9 @@
if(mob.machine.relaymove(mob,direct))
return
if(istype(mob.buckled, /obj/vehicle))
return mob.buckled.relaymove(mob,direct)
if(mob.pulledby || mob.buckled) // Wheelchair driving!
if(istype(mob.loc, /turf/space))
return // No wheelchair driving in space
+1 -1
View File
@@ -816,7 +816,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))
/datum/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam))
return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam - 11))
//for arms and hands
/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
@@ -52,7 +52,7 @@
///////////LASER RIFLE//////////////
/obj/item/weapon/gun/energy/rifle/laser
name = "laser rifle"
desc = "a basic weapon designed kill with concentrated energy bolts"
desc = "a basic weapon designed to kill with concentrated energy bolts"
icon_state = "laser"
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
@@ -1,6 +1,6 @@
/obj/item/weapon/gun/energy/laser
name = "laser rifle"
desc = "a basic weapon designed kill with concentrated energy bolts"
desc = "a basic weapon designed to kill with concentrated energy bolts"
icon_state = "laser"
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
+3 -1
View File
@@ -38,12 +38,14 @@
loaded -= AC //Remove casing from loaded list.
if(isnull(AC) || !istype(AC))
return 0
AC.loc = get_turf(src) //Eject casing onto ground.
if(ejectshell == 1)
AC.loc = get_turf(src) //Eject casing onto ground. If 0, casings stay in the gun. Totally a good idea trust me okay.
if(AC.BB)
AC.desc += " This one is spent." //descriptions are magic - only when there's a projectile in the casing
in_chamber = AC.BB //Load projectile into chamber.
AC.BB.loc = src //Set projectile loc to gun.
return 1
return 0
@@ -0,0 +1,179 @@
/obj/item/weapon/gun/projectile/laser //butts
desc = "a basic weapon designed to kill with concentrated energy bolts."
name = "laser rifle"
caliber = "laser"
w_class = 3.0
recoil = 0
ammo_type = "/obj/item/ammo_casing/laser"
max_shells = 100
load_method = 2 //0 = Single shells or quick loader, 1 = box, 2 = magazine
fire_delay = 6
ejectshell = 0
slot_flags = SLOT_BACK
var/modded = 0
var/obj/item/weapon/reloadlasermodkit/mod
//placeholders//
icon_state = "laser"
item_state = "laser"
fire_sound = 'sound/weapons/Laser.ogg'
//placeholders// Well, okay, not the sound.
New()
for(var/i = 1, i <= 30, i++)
loaded += new ammo_type(src)
update_icon()
empty_mag = new /obj/item/ammo_magazine/laser/empty(src)
update_icon()
return
/obj/item/ammo_magazine/laser/empty
max_ammo = 0
/obj/item/ammo_magazine/laser
name = "charge cell (laser)"
desc = "A standard 30-shot cell."
icon_state = "12mm"
origin_tech = "combat=2"
ammo_type = "/obj/item/ammo_casing/laser"
max_ammo = 30
// multiple_sprites = 1
/obj/item/ammo_magazine/laser/pulse
name = "charge cell (pulse)"
desc = "A heavy-duty 15-shot pulse cell."
ammo_type = "/obj/item/ammo_casing/laser/pulse"
max_ammo = 15
/obj/item/ammo_magazine/laser/heavy
name = "charge cell (heavy)"
desc = "A 15-shot cell designed to overload your projectiles with an extremely heavy charge."
ammo_type = "/obj/item/ammo_casing/laser/heavy"
max_ammo = 15
/obj/item/ammo_magazine/laser/practice
name = "charge cell (practice)"
desc = "A hundred-shot cell keyed in to a harmless wavelength for practice shooting."
ammo_type = "/obj/item/ammo_casing/laser/practice"
max_ammo = 100
/obj/item/ammo_magazine/laser/light
name = "charge cell (light)"
desc = "A 60-shot cell designed with capacity in mind. The lasers are weaker, though."
ammo_type = "/obj/item/ammo_casing/laser/light"
max_ammo = 60
/obj/item/ammo_magazine/laser/stun
name = "charge cell (stun)"
desc = "A 20-shot cell that fires lethal incapacitating bolts. Not standard issue."
ammo_type = "/obj/item/ammo_casing/laser/stun"
max_ammo = 20
////////////////////////////
//Shells for the magazines//
////////////////////////////
//don't spawn these you butts//
/obj/item/ammo_casing/laser
desc = "A LASER SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam"
/obj/item/ammo_casing/laser/pulse
desc = "A PULSE SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam/pulse"
/obj/item/ammo_casing/laser/heavy
desc = "A LASER CANNON SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam/heavylaser"
/obj/item/ammo_casing/laser/practice
desc = "A PRACTICE BLANK FAKE LASER SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam/practice"
/obj/item/ammo_casing/laser/light
desc = "A LIGHT LASER XRAY SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam/xray/burst"
/obj/item/ammo_casing/laser/stun
desc = "A STUN LASER SHELL. You shouldn't be seeing this."
caliber = "laser"
projectile_type = "/obj/item/projectile/beam/stun"
////////////////////////////////
//////////////mods//////////////
////////////////////////////////
/obj/item/weapon/reloadlasermodkit
desc = "A cheap, disposable modkit designed to rapidly and permanently augment NT-standard laser rifles."
name = "rifle nanokit"
var/modtype = 0
var/uses = 1
var/emagged
icon = 'icons/obj/assemblies.dmi'
icon_state = "posibrain" //the placeholders are real
/* Not sure about this yet.
/obj/item/device/megaphone/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
user << "\red You sneakily unlock the highly illegal military-grade burstfire augment."
emagged = 1
return
return
*/
/obj/item/weapon/reloadlasermodkit/attack_self(var/mob/user as mob)
if (!emagged)
if (modtype == 0)
user << "<span class='notice'>Size modification selected.</span>"
modtype = 1
else if (modtype == 1)
user << "<span class='notice'>Rapid-fire modification selected.</span>"
modtype = 2
else if (modtype == 2)
user << "<span class='notice'>Silencer modification selected.</span>"
modtype = 0
else if (emagged) //We'll see. Burst is ridiculous, especially on a full-power laser.
user << "<span class='notice'>Burstfire modification selected.</span>"
modtype = 3
/obj/item/weapon/gun/projectile/laser/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/reloadlasermodkit))
if(user.l_hand != src && user.r_hand != src) //if we're not in his hands
user << "<span class='notice'>You'll need [src] in your hands to do that.</span>"
return
if(src.modded == 1)
user << "<span class='notice'>The frame can only handle one mod.</span>"
return
user.drop_item()
user << "<span class='notice'>You activate the modkit and watch the nanites swarm over [src].</span>"
I.loc = src.mod
src.mod = I
src.modded = 1
if (mod.modtype == 0)
user << "<span class='notice'>[src]'s firerate has been increased.</span>"
src.fire_delay = 4
else if (mod.modtype == 1)
user << "<span class='notice'>[src]'s shape changes rapidly, becoming smaller and more economical.</span>"
src.w_class = 3
else if (mod.modtype == 2)
user << "<span class='notice'>[src] sprouts wave-cancelling emitters. Its shots are now silenced.</span>"
src.silenced = 1
else if (mod.modtype == 3)
user << "<span class='notice'>[src] rapidly reshapes its firing mechanism. It now fires in bursts.</span>"
src.fire_delay = 0
src.projectiles_per_shot = 3
src.fire_cooldown = 1
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
return
..()
+1 -1
View File
@@ -87,7 +87,7 @@
return 0// nope.avi
var/distance = get_dist(starting,loc)
var/miss_modifier = -30
var/miss_modifier = -60
if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
+4 -3
View File
@@ -99,12 +99,13 @@ var/list/beam_master = list()
name = "xray beam"
icon_state = "xray"
damage = 30
// forcedodge = -1
/obj/item/projectile/beam/xray/burst
name = "xray beam"
icon_state = "xray"
// damage = 15 this makes rapidlasers kill almost exactly as fast as the rifle, but since they do a tripleburst, armor is much more effective. plus. rng miss.
damage = 20 //hence 20 damage. slight advantage over regular lasers. half-capacity for damage. use for coolness. use laser cannons for powergame.
damage = 25 //hence 25 damage. slight advantage over regular lasers. half-capacity for damage. use for coolness. use laser cannons for powergame.
/obj/item/projectile/beam/pulse
name = "pulse"
@@ -122,10 +123,10 @@ var/list/beam_master = list()
icon_state = "emitter"
damage = 30
/obj/item/projectile/beam/stunrevolver
/obj/item/projectile/beam/stun
name = "stun beam"
icon_state = "stun"
damage = 10
damage = 20
agony = 45
/obj/item/projectile/beam/lastertag/blue
@@ -88,3 +88,30 @@
*/
agony = 70
damage_type = HALLOSS
/obj/item/projectile/energy/mining //not in the game. i'll play with it later probably.
name = "electrode"
icon_state = "spark"
damage = 5
kill_count = 3
var/life = 5
Bump(atom/A)
A.bullet_act(src, def_zone)
src.life -= 1
if(life <= 0)
del(src)
return
/turf/simulated/mineral/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/energy/mining))
src.GetDrilled()
..()
return 0
/obj/structure/boulder/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/energy/mining))
del(src)
..()
return 0
@@ -20,7 +20,7 @@
icon_state = "cespace_suit"
item_state = "cespace_suit"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank, /obj/item/device/suit_cooling_unit)
/obj/item/clothing/head/helmet/space/anomaly
name = "Excavation hood"
+303
View File
@@ -0,0 +1,303 @@
/obj/vehicle/train/cargo/engine
name = "cargo train tug"
desc = "A ridable electric car designed for pulling cargo trolleys."
icon = 'icons/obj/vehicles.dmi'
icon_state = "cargo_engine"
on = 0
powered = 1
locked = 0
load_item_visible = 1
load_offset_x = 0
mob_offset_y = 7
var/car_limit = 3 //how many cars an engine can pull before performance degrades
active_engines = 1
var/obj/item/weapon/key/cargo_train/key
/obj/item/weapon/key/cargo_train
name = "key"
desc = "A keyring with a small steel key, and a yellow fob reading \"Choo Choo!\"."
icon = 'icons/obj/vehicles.dmi'
icon_state = "train_keys"
w_class = 1
/obj/vehicle/train/cargo/trolley
name = "cargo train trolley"
icon = 'icons/obj/vehicles.dmi'
icon_state = "cargo_trailer"
anchored = 0
passenger_allowed = 0
locked = 0
load_item_visible = 1
load_offset_x = 0
load_offset_y = 4
mob_offset_y = 8
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/New()
..()
cell = new /obj/item/weapon/cell/high
verbs -= /atom/movable/verb/pull
key = new()
var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
overlays += I
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/cargo/engine/Move()
if(on && cell.charge < charge_use)
turn_off()
update_stats()
if(load && is_train_head())
load << "The drive motor briefly whines, then drones to a stop."
if(is_train_head() && !on)
return 0
return ..()
/obj/vehicle/train/cargo/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(open && istype(W, /obj/item/weapon/wirecutters))
passenger_allowed = !passenger_allowed
user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>")
else
..()
/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/key/cargo_train))
if(!key)
user.drop_item()
W.forceMove(src)
key = W
verbs += /obj/vehicle/train/cargo/engine/verb/remove_key
return
..()
/obj/vehicle/train/cargo/update_icon()
if(open)
icon_state = initial(icon_state) + "_open"
else
icon_state = initial(icon_state)
/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
return
/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/cargo/engine/remove_cell(var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/cargo/engine/Bump(atom/Obstacle)
var/obj/machinery/door/D = Obstacle
var/mob/living/carbon/human/H = load
if(istype(D) && istype(H))
D.Bumped(H) //a little hacky, but hey, it works, and respects access rights
..()
/obj/vehicle/train/cargo/trolley/Bump(atom/Obstacle)
if(!lead)
return //so people can't knock others over by pushing a trolley around
..()
//-------------------------------------------
// Train procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/turn_on()
if(!key)
return
else
..()
update_stats()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(on)
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
/obj/vehicle/train/cargo/engine/turn_off()
..()
verbs -= /obj/vehicle/train/cargo/engine/verb/stop_engine
verbs -= /obj/vehicle/train/cargo/engine/verb/start_engine
if(!on)
verbs += /obj/vehicle/train/cargo/engine/verb/start_engine
else
verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine
/obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts))
/obj/vehicle/train/cargo/trolley/RunOver(var/mob/living/carbon/human/H)
..()
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
/obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H)
..()
if(is_train_head() && istype(load, /mob/living/carbon/human))
var/mob/living/carbon/human/D = load
D << "\red \b You ran over [H]!"
visible_message("<B>\red \The [src] ran over [H]!</B>")
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])</font>")
msg_admin_attack("[D.name] ([D.ckey]) ran over [H.name] ([H.ckey]). (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
else
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/cargo/engine/relaymove(mob/user, direction)
if(user != load)
return 0
if(is_train_head())
if(direction == reverse_direction(dir) && tow)
return 0
if(Move(get_step(src, direction)))
return 1
return 0
else
return ..()
/obj/vehicle/train/cargo/engine/examine()
..()
if(!istype(usr, /mob/living/carbon/human))
return
if(get_dist(usr,src) <= 1)
usr << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
usr << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%"
/obj/vehicle/train/cargo/engine/verb/start_engine()
set name = "Start engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(on)
usr << "The engine is already running."
return
turn_on()
if (on)
usr << "You start [src]'s engine."
else
if(cell.charge < charge_use)
usr << "[src] is out of power."
else
usr << "[src]'s engine won't start."
/obj/vehicle/train/cargo/engine/verb/stop_engine()
set name = "Stop engine"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!on)
usr << "The engine is already stopped."
return
turn_off()
if (!on)
usr << "You stop [src]'s engine."
/obj/vehicle/train/cargo/engine/verb/remove_key()
set name = "Remove key"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!key || (load && load != usr))
return
if(on)
turn_off()
key.loc = usr.loc
if(!usr.get_active_hand())
usr.put_in_hands(key)
key = null
verbs -= /obj/vehicle/train/cargo/engine/verb/remove_key
//-------------------------------------------
// Loading/unloading procs
//-------------------------------------------
/obj/vehicle/train/cargo/trolley/load(var/atom/movable/C)
if(ismob(C) && !passenger_allowed)
return 0
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human))
return 0
..()
if(load)
return 1
/obj/vehicle/train/cargo/engine/load(var/atom/movable/C)
if(!istype(C, /mob/living/carbon/human))
return 0
return ..()
//-------------------------------------------------------
// Stat update procs
//
// Update the trains stats for speed calculations.
// The longer the train, the slower it will go. car_limit
// sets the max number of cars one engine can pull at
// full speed. Adding more cars beyond this will slow the
// train proportionate to the length of the train. Adding
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/cargo/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
//Update move delay
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/cargo/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
if(!lead && !tow)
anchored = 0
if(verbs.Find(/atom/movable/verb/pull))
return
else
verbs += /atom/movable/verb/pull
else
anchored = 1
verbs -= /atom/movable/verb/pull
+229
View File
@@ -0,0 +1,229 @@
/obj/vehicle/train
name = "train"
dir = 4
move_delay = 1
health = 100
maxhealth = 100
fire_dam_coeff = 0.7
brute_dam_coeff = 0.5
var/passenger_allowed = 1
var/active_engines = 0
var/train_length = 0
var/obj/vehicle/train/lead
var/obj/vehicle/train/tow
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/initialize()
for(var/obj/vehicle/train/T in orange(1, src))
latch(T)
/obj/vehicle/train/Move()
var/old_loc = get_turf(src)
if(..())
if(tow)
tow.Move(old_loc)
return 1
else
if(lead)
unattach()
return 0
/obj/vehicle/train/Bump(atom/Obstacle)
if(!istype(Obstacle, /atom/movable))
return
var/atom/movable/A = Obstacle
if(!A.anchored)
var/turf/T = get_step(A, dir)
if(isturf(T))
A.Move(T) //bump things away when hit
if(emagged)
if(istype(A, /mob/living))
var/mob/living/M = A
visible_message("\red [src] knocks over [M]!")
M.apply_effects(5, 5) //knock people down if you hit them
M.apply_damages(22 / move_delay) // and do damage according to how fast the train is going
if(istype(load, /mob/living/carbon/human))
var/mob/living/D = load
D << "\red You hit [M]!"
msg_admin_attack("[D.name] ([D.ckey]) hit [M.name] ([M.ckey]) with [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
//-------------------------------------------
// Vehicle procs
//-------------------------------------------
/obj/vehicle/train/explode()
if (tow)
tow.unattach()
unattach()
..()
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/relaymove(mob/user, direction)
var/turf/T = get_step_to(src, get_step(src, direction))
if(!T)
user << "You can't find a clear area to step onto."
return 0
if(user != load)
if(user in src) //for handling players stuck in src - this shouldn't happen - but just in case it does
user.forceMove(T)
return 1
return 0
unload(user, direction)
user << "\blue You climb down from [src]."
return 1
/obj/vehicle/train/MouseDrop_T(var/atom/movable/C, mob/user as mob)
if(user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !user.canmove))
return
if(istype(C,/obj/vehicle/train))
latch(C, user)
else
if(!load(C))
user << "\red You were unable to load [C] on [src]."
/obj/vehicle/train/attack_hand(mob/user as mob)
if(user.stat || user.restrained() || !Adjacent(user))
return 0
if(user != load && (user in src))
user.forceMove(loc) //for handling players stuck in src
else if(load)
unload(user) //unload if loaded
else if(!load && !user.buckled)
load(user) //else try climbing on board
else
return 0
/obj/vehicle/train/verb/unlatch_v()
set name = "Unlatch"
set desc = "Unhitches this train from the one in front of it."
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living/carbon/human))
return
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
return
unattach(usr)
//-------------------------------------------
// Latching/unlatching procs
//-------------------------------------------
//attempts to attach src as a follower of the train T
/obj/vehicle/train/proc/attach_to(obj/vehicle/train/T, mob/user)
if (get_dist(src, T) > 1)
user << "\red [src] is too far away from [T] to hitch them together."
return
if (lead)
user << "\red [src] is already hitched to something."
return
if (T.tow)
user << "\red [T] is already towing something."
return
//check for cycles.
var/obj/vehicle/train/next_car = T
while (next_car)
if (next_car == src)
user << "\red That seems very silly."
return
next_car = next_car.lead
//latch with src as the follower
lead = T
T.tow = src
dir = lead.dir
if(user)
user << "\blue You hitch [src] to [T]."
update_stats()
//detaches the train from whatever is towing it
/obj/vehicle/train/proc/unattach(mob/user)
if (!lead)
user << "\red [src] is not hitched to anything."
return
lead.tow = null
lead.update_stats()
user << "\blue You unhitch [src] from [lead]."
lead = null
update_stats()
/obj/vehicle/train/proc/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T))
return 0
var/T_dir = get_dir(src, T) //figure out where T is wrt src
if(dir == T_dir) //if car is ahead
src.attach_to(T, user)
else if(reverse_direction(dir) == T_dir) //else if car is behind
T.attach_to(src, user)
//returns 1 if this is the lead car of the train
/obj/vehicle/train/proc/is_train_head()
if (lead)
return 0
return 1
//-------------------------------------------------------
// Stat update procs
//
// Used for updating the stats for how long the train is.
// These are useful for calculating speed based on the
// size of the train, to limit super long trains.
//-------------------------------------------------------
/obj/vehicle/train/update_stats()
//first, seek to the end of the train
var/obj/vehicle/train/T = src
while(T.tow)
//check for cyclic train.
if (T.tow == src)
lead.tow = null
lead.update_stats()
lead = null
update_stats()
return
T = T.tow
//now walk back to the front.
var/active_engines = 0
var/train_length = 0
while(T)
train_length++
if (powered && on)
active_engines++
T.update_car(train_length, active_engines)
T = T.lead
/obj/vehicle/train/proc/update_car(var/train_length, var/active_engines)
return
+358
View File
@@ -0,0 +1,358 @@
/obj/vehicle
name = "vehicle"
icon = 'icons/obj/vehicles.dmi'
layer = MOB_LAYER + 0.1 //so it sits above objects including mobs
density = 1
anchored = 1
animate_movement=1
luminosity = 3
var/attack_log = null
var/on = 0
var/health = 0 //do not forget to set health for your vehicle!
var/maxhealth = 0
var/fire_dam_coeff = 1.0
var/brute_dam_coeff = 1.0
var/open = 0 //Maint panel
var/locked = 1
var/stat = 0
var/emagged = 0
var/powered = 0 //set if vehicle is powered and should use fuel when moving
var/move_delay = 1 //set this to limit the speed of the vehicle
var/movable = 1
var/obj/item/weapon/cell/cell
var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
var/load_offset_x = 0 //pixel_x offset for item overlay
var/load_offset_y = 0 //pixel_y offset for item overlay
var/mob_offset_y = 0 //pixel_y offset for mob overlay
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/New()
..()
//spawn the cell you want in each vehicle
/obj/vehicle/Move()
if(world.time > l_move_time + move_delay)
if(on && powered && cell.charge < charge_use)
turn_off()
var/init_anc = anchored
anchored = 0
if(!..())
anchored = init_anc
return 0
anchored = init_anc
if(on && powered)
cell.use(charge_use)
if(load)
load.forceMove(loc)// = loc
load.dir = dir
return 1
else
return 0
/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/hand_labeler))
return
if(istype(W, /obj/item/weapon/screwdriver))
if(!locked)
open = !open
update_icon()
user << "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>"
else if(istype(W, /obj/item/weapon/crowbar) && cell && open)
remove_cell(user)
else if(istype(W, /obj/item/weapon/cell) && !cell && open)
insert_cell(W, user)
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/T = W
if(T.welding)
if(health < maxhealth)
if(open)
health = min(maxhealth, health+10)
user.visible_message("\red [user] repairs [src]!","\blue You repair [src]!")
else
user << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
else
user << "<span class='notice'>[src] does not need a repair.</span>"
else
user << "<span class='notice'>Unable to repair while [src] is off.</span>"
else if(istype(W, /obj/item/weapon/card/emag) && !emagged)
Emag(user)
else if(hasvar(W,"force") && hasvar(W,"damtype"))
switch(W.damtype)
if("fire")
health -= W.force * fire_dam_coeff
if("brute")
health -= W.force * brute_dam_coeff
..()
healthcheck()
else
..()
/obj/vehicle/attack_animal(var/mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0) return
health -= M.melee_damage_upper
src.visible_message("\red <B>[M] has [M.attacktext] [src]!</B>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>")
if(prob(10))
new /obj/effect/decal/cleanable/blood/oil(src.loc)
healthcheck()
/obj/vehicle/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
/obj/vehicle/meteorhit()
explode()
return
/obj/vehicle/blob_act()
src.health -= rand(20,40)*fire_dam_coeff
healthcheck()
return
/obj/vehicle/ex_act(severity)
switch(severity)
if(1.0)
explode()
return
if(2.0)
health -= rand(5,10)*fire_dam_coeff
health -= rand(10,20)*brute_dam_coeff
healthcheck()
return
if(3.0)
if (prob(50))
health -= rand(1,5)*fire_dam_coeff
health -= rand(1,5)*brute_dam_coeff
healthcheck()
return
return
/obj/vehicle/emp_act(severity)
var/was_on = on
stat |= EMPED
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc )
pulse2.icon = 'icons/effects/effects.dmi'
pulse2.icon_state = "empdisable"
pulse2.name = "emp sparks"
pulse2.anchored = 1
pulse2.dir = pick(cardinal)
spawn(10)
pulse2.delete()
if(on)
turn_off()
spawn(severity*300)
stat &= ~EMPED
if(was_on)
turn_on()
/obj/vehicle/attack_ai(mob/user as mob)
return
/obj/vehicle/proc/handle_rotation()
return
//-------------------------------------------
// Vehicle procs
//-------------------------------------------
/obj/vehicle/proc/turn_on()
if(stat)
return 0
if(powered && cell.charge < charge_use)
return 0
on = 1
luminosity = initial(luminosity)
update_icon()
return 1
/obj/vehicle/proc/turn_off()
on = 0
luminosity = 0
update_icon()
/obj/vehicle/proc/Emag(mob/user as mob)
emagged = 1
if(locked)
locked = 0
user << "<span class='warning'>You bypass [src]'s controls.</span>"
/obj/vehicle/proc/explode()
src.visible_message("\red <B>[src] blows apart!</B>", 1)
var/turf/Tsec = get_turf(src)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/rods(Tsec)
// new /obj/item/stack/cable_coil/cut(Tsec) THIS DOESN'T WORK SO I'M GETTING RID OF IT.
if(cell)
cell.forceMove(Tsec)
cell.update_icon()
cell = null
//stuns people who are thrown off a train that has been blown up
if(istype(load, /mob/living))
var/mob/living/M = load
M.apply_effects(5, 5)
unload()
new /obj/effect/gibspawner/robot(Tsec)
new /obj/effect/decal/cleanable/blood/oil(src.loc)
del(src)
/obj/vehicle/proc/healthcheck()
if(health <= 0)
explode()
/obj/vehicle/proc/powercheck()
if(!cell && !powered)
return
if(!cell && powered)
turn_off()
return
if(cell.charge < charge_use)
turn_off()
return
if(cell && powered)
turn_on()
return
/obj/vehicle/proc/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
if(cell)
return
if(!istype(C))
return
H.drop_from_inventory(C)
C.forceMove(src)
cell = C
powercheck()
usr << "<span class='notice'>You install [C] in [src].</span>"
/obj/vehicle/proc/remove_cell(var/mob/living/carbon/human/H)
if(!cell)
return
usr << "<span class='notice'>You remove [cell] from [src].</span>"
cell.forceMove(get_turf(H))
H.put_in_hands(cell)
cell = null
powercheck()
/obj/vehicle/proc/RunOver(var/mob/living/carbon/human/H)
return //write specifics for different vehicles
//-------------------------------------------
// Loading/unloading procs
//
// Set specific item restriction checks in
// the vehicle load() definition before
// calling this parent proc.
//-------------------------------------------
/obj/vehicle/proc/load(var/atom/movable/C)
//define allowed items for loading in specific vehicle definitions
if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly.
return 0
if(load || C.anchored)
return 0
// if a create/closet, close before loading
var/obj/structure/closet/crate = C
if(istype(crate))
crate.close()
C.forceMove(loc)
C.dir = dir
C.anchored = 1
load = C
if(load_item_visible)
C.pixel_x += load_offset_x
if(ismob(C))
C.pixel_y += mob_offset_y
else
C.pixel_y += load_offset_y
C.layer = layer + 0.1 //so it sits above the vehicle
if(ismob(C))
var/mob/M = C
M.buckled = src
M.update_canmove()
return 1
/obj/vehicle/proc/unload(var/mob/user, var/direction)
if(!load)
return
var/turf/dest = null
//find a turf to unload to
if(direction) //if direction specified, unload in that direction
dest = get_step(src, direction)
else if(user) //if a user has unloaded the vehicle, unload at their feet
dest = get_turf(user)
if(!dest)
dest = get_step_to(src, get_step(src, turn(dir, 90))) //try unloading to the side of the vehicle first if neither of the above are present
//if these all result in the same turf as the vehicle or nullspace, pick a new turf with open space
if(!dest || dest == get_turf(src))
var/list/options = new()
for(var/test_dir in alldirs)
var/new_dir = get_step_to(src, get_step(src, test_dir))
if(new_dir && load.Adjacent(new_dir))
options += new_dir
if(options.len)
dest = pick(options)
else
dest = get_turf(src) //otherwise just dump it on the same turf as the vehicle
if(!isturf(dest)) //if there still is nowhere to unload, cancel out since the vehicle is probably in nullspace
return 0
load.forceMove(dest)
load.dir = get_dir(loc, dest)
load.anchored = initial(load.anchored)
load.pixel_x = initial(load.pixel_x)
load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer)
if(ismob(load))
var/mob/M = load
M.buckled = null
M.anchored = initial(M.anchored)
M.update_canmove()
load = null
return 1
//-------------------------------------------------------
// Stat update procs
//-------------------------------------------------------
/obj/vehicle/proc/update_stats()
return