Merge branch 'master' of https://github.com/PolarisSS13/Polaris into 2/28/2016_armor

This commit is contained in:
Neerti
2016-03-06 04:19:33 -05:00
111 changed files with 1043 additions and 4407 deletions

View File

@@ -63,7 +63,6 @@ var/list/be_special_flags = list(
// Mode/antag template macros.
#define MODE_BORER "borer"
#define MODE_XENOMORPH "xeno"
#define MODE_LOYALIST "loyalist"
#define MODE_MUTINEER "mutineer"
#define MODE_COMMANDO "commando"

View File

@@ -1,5 +1,5 @@
// Species flags.
#define NO_MINOR_CUT 0x1 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows)
#define NO_MINOR_CUT 0x1 // Can step on broken glass with no ill-effects. Either thick skin (diona), cut resistant (slimes) or incorporeal (shadows)
#define IS_PLANT 0x2 // Is a treeperson.
#define NO_SCAN 0x4 // Cannot be scanned in a DNA machine/genome-stolen.
#define NO_PAIN 0x8 // Cannot suffer halloss/recieves deceptive health indicator.

View File

@@ -1,10 +1,6 @@
/atom/movable/proc/get_mob()
return
/obj/machinery/bot/mulebot/get_mob()
if(load && istype(load,/mob/living))
return load
/obj/mecha/get_mob()
return occupant
@@ -14,6 +10,11 @@
/mob/get_mob()
return src
/mob/living/bot/mulebot/get_mob()
if(load && istype(load, /mob/living))
return list(src, load)
return src
/proc/mobs_in_view(var/range, var/source)
var/list/mobs = list()
for(var/atom/movable/AM in view(range, source))

View File

@@ -20,7 +20,7 @@
return // seems legit.
// Things you might plausibly want to follow
if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/singularity))
if((ismob(A) && A != src) || istype(A,/obj/singularity))
ManualFollow(A)
// Otherwise jump

View File

@@ -278,11 +278,11 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
group = "Miscellaneous"
/datum/supply_packs/mule
name = "MULEbot Crate"
contains = list(/obj/machinery/bot/mulebot)
name = "Mulebot Crate"
contains = list()
cost = 20
containertype = /obj/structure/largecrate/mule
containername = "MULEbot Crate"
containertype = /obj/structure/largecrate/animal/mulebot
containername = "Mulebot Crate"
group = "Operations"
/datum/supply_packs/cargotrain

View File

@@ -1,65 +0,0 @@
/datum/wires/mulebot
random = 1
holder_type = /obj/machinery/bot/mulebot
wire_count = 10
var/const/WIRE_POWER1 = 1 // power connections
var/const/WIRE_POWER2 = 2
var/const/WIRE_AVOIDANCE = 4 // mob avoidance
var/const/WIRE_LOADCHECK = 8 // load checking (non-crate)
var/const/WIRE_MOTOR1 = 16 // motor wires
var/const/WIRE_MOTOR2 = 32 //
var/const/WIRE_REMOTE_RX = 64 // remote recv functions
var/const/WIRE_REMOTE_TX = 128 // remote trans status
var/const/WIRE_BEACON_RX = 256 // beacon ping recv
/datum/wires/mulebot/CanUse(var/mob/living/L)
var/obj/machinery/bot/mulebot/M = holder
if(M.open)
return 1
return 0
// So the wires do not open a new window, handle the interaction ourselves.
/datum/wires/mulebot/Interact(var/mob/living/user)
if(CanUse(user))
var/obj/machinery/bot/mulebot/M = holder
M.interact(user)
/datum/wires/mulebot/UpdatePulsed(var/index)
switch(index)
if(WIRE_POWER1, WIRE_POWER2)
holder.visible_message("<span class='notice'>\icon[holder] The charge light flickers.</span>")
if(WIRE_AVOIDANCE)
holder.visible_message("<span class='notice'>\icon[holder] The external warning lights flash briefly.</span>")
if(WIRE_LOADCHECK)
holder.visible_message("<span class='notice'>\icon[holder] The load platform clunks.</span>")
if(WIRE_MOTOR1, WIRE_MOTOR2)
holder.visible_message("<span class='notice'>\icon[holder] The drive motor whines briefly.</span>")
else
holder.visible_message("<span class='notice'>\icon[holder] You hear a radio crackle.</span>")
// HELPER PROCS
/datum/wires/mulebot/proc/Motor1()
return !(wires_status & WIRE_MOTOR1)
/datum/wires/mulebot/proc/Motor2()
return !(wires_status & WIRE_MOTOR2)
/datum/wires/mulebot/proc/HasPower()
return !(wires_status & WIRE_POWER1) && !(wires_status & WIRE_POWER2)
/datum/wires/mulebot/proc/LoadCheck()
return !(wires_status & WIRE_LOADCHECK)
/datum/wires/mulebot/proc/MobAvoid()
return !(wires_status & WIRE_AVOIDANCE)
/datum/wires/mulebot/proc/RemoteTX()
return !(wires_status & WIRE_REMOTE_TX)
/datum/wires/mulebot/proc/RemoteRX()
return !(wires_status & WIRE_REMOTE_RX)
/datum/wires/mulebot/proc/BeaconRX()
return !(wires_status & WIRE_BEACON_RX)

View File

@@ -1,7 +1,8 @@
var/datum/antagonist/xenos/borer/borers
var/datum/antagonist/borer/borers
/datum/antagonist/xenos/borer
/datum/antagonist/borer
id = MODE_BORER
role_type = BE_ALIEN
role_text = "Cortical Borer"
role_text_plural = "Cortical Borers"
mob_path = /mob/living/simple_animal/borer
@@ -10,6 +11,8 @@ var/datum/antagonist/xenos/borer/borers
antag_indicator = "brainworm"
antaghud_indicator = "hudborer"
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
faction_role_text = "Borer Thrall"
faction_descriptor = "Unity"
faction_welcome = "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head."
@@ -17,21 +20,26 @@ var/datum/antagonist/xenos/borer/borers
initial_spawn_req = 3
initial_spawn_target = 5
/datum/antagonist/xenos/borer/New()
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
spawn_announcement_title = "Lifesign Alert"
spawn_announcement_sound = 'sound/AI/aliens.ogg'
spawn_announcement_delay = 5000
/datum/antagonist/borer/New()
..(1)
borers = src
/datum/antagonist/xenos/borer/get_extra_panel_options(var/datum/mind/player)
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[put in host\]</a>"
/datum/antagonist/xenos/borer/create_objectives(var/datum/mind/player)
/datum/antagonist/borer/create_objectives(var/datum/mind/player)
if(!..())
return
player.objectives += new /datum/objective/borer_survive()
player.objectives += new /datum/objective/borer_reproduce()
player.objectives += new /datum/objective/escape()
/datum/antagonist/xenos/borer/place_mob(var/mob/living/mob)
/datum/antagonist/borer/place_mob(var/mob/living/mob)
var/mob/living/simple_animal/borer/borer = mob
if(istype(borer))
var/mob/living/carbon/human/host
@@ -51,4 +59,16 @@ var/datum/antagonist/xenos/borer/borers
borer.host_brain.name = host.name
borer.host_brain.real_name = host.real_name
return
..() // Place them at a vent if they can't get a host.
// Place them at a vent if they can't get a host.
borer.forceMove(get_turf(pick(get_vents())))
/datum/antagonist/borer/attempt_random_spawn()
if(config.aliens_allowed) ..()
/datum/antagonist/borer/proc/get_vents()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
return vents

View File

@@ -1,47 +0,0 @@
var/datum/antagonist/xenos/xenomorphs
/datum/antagonist/xenos
id = MODE_XENOMORPH
role_type = BE_ALIEN
role_text = "Xenomorph"
role_text_plural = "Xenomorphs"
mob_path = /mob/living/carbon/alien/larva
bantype = "Xenomorph"
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
antaghud_indicator = "hudalien"
hard_cap = 5
hard_cap_round = 8
initial_spawn_req = 4
initial_spawn_target = 6
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
spawn_announcement_title = "Lifesign Alert"
spawn_announcement_sound = 'sound/AI/aliens.ogg'
spawn_announcement_delay = 5000
/datum/antagonist/xenos/New(var/no_reference)
..()
if(!no_reference)
xenomorphs = src
/datum/antagonist/xenos/attempt_random_spawn()
if(config.aliens_allowed) ..()
/datum/antagonist/xenos/proc/get_vents()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
return vents
/datum/antagonist/xenos/create_objectives(var/datum/mind/player)
if(!..())
return
player.objectives += new /datum/objective/survive()
player.objectives += new /datum/objective/escape()
/datum/antagonist/xenos/place_mob(var/mob/living/player)
player.forceMove(get_turf(pick(get_vents())))

View File

@@ -161,7 +161,7 @@ var/datum/antagonist/raider/raiders
else
win_type = "Minor"
win_group = "Crew"
//Now we modify that result by the state of the vox crew.
//Now we modify that result by the state of the crew.
if(antags_are_dead())
win_type = "Major"
win_group = "Crew"
@@ -198,26 +198,23 @@ var/datum/antagonist/raider/raiders
if(!..())
return 0
if(player.species && player.species.get_bodytype() == "Vox")
equip_vox(player)
else
var/new_shoes = pick(raider_shoes)
var/new_uniform = pick(raider_uniforms)
var/new_glasses = pick(raider_glasses)
var/new_helmet = pick(raider_helmets)
var/new_suit = pick(raider_suits)
var/new_shoes = pick(raider_shoes)
var/new_uniform = pick(raider_uniforms)
var/new_glasses = pick(raider_glasses)
var/new_helmet = pick(raider_helmets)
var/new_suit = pick(raider_suits)
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
if(!player.shoes)
//If equipping shoes failed, fall back to equipping sandals
var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
if(!player.shoes)
//If equipping shoes failed, fall back to equipping sandals
var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
equip_weapons(player)
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
equip_weapons(player)
var/obj/item/weapon/card/id/id = create_id("Visitor", player, equip = 0)
id.name = "[player.real_name]'s Passport"
@@ -293,21 +290,3 @@ var/datum/antagonist/raider/raiders
var/grenade_type = pick(grenades)
new grenade_type(ammobox)
player.put_in_any_hand_if_possible(ammobox)
/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player)
var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual))
player.equip_to_slot_or_del(new uniform_type(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(player), slot_gloves) // AS ABOVE.
player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat/vox(player), slot_wear_mask)
player.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store)
player.internal = locate(/obj/item/weapon/tank) in player.contents
if(istype(player.internal,/obj/item/weapon/tank) && player.internals)
player.internals.icon_state = "internal1"
return 1

View File

@@ -350,11 +350,6 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
M << "<br>"
M.add_ion_law("THE STATION IS [who2pref] [who2]")
if(botEmagChance)
for(var/obj/machinery/bot/bot in machines)
if(prob(botEmagChance))
bot.emag_act(1)
/*
var/apcnum = 0

View File

@@ -254,13 +254,13 @@ var/global/list/additional_antag_types = list()
"suspected criminal operatives",
"malfunctioning von Neumann probe swarms",
"shadowy interlopers",
"a stranded Vox arkship",
"a stranded alien arkship",
"haywire IPC constructs",
"rogue Unathi exiles",
"artifacts of eldritch horror",
"a brain slug infestation",
"killer bugs that lay eggs in the husks of the living",
"a deserted transport carrying xenomorph specimens",
"a deserted transport carrying alien specimens",
"an emissary for the gestalt requesting a security detail",
"a Tajaran slave rebellion",
"radical Skrellian transevolutionaries",

View File

@@ -1,14 +0,0 @@
/datum/game_mode/bughunt
name = "Bughunt"
round_description = "A mercenary strike force is approaching the station to eradicate a xenomorph infestation!"
extended_round_description = "Mercenaries and xenomorphs spawn in this game mode."
config_tag = "bughunt"
required_players = 15
required_players_secret = 25
required_enemies = 1
end_on_antag_death = 1
antag_tags = list(MODE_XENOMORPH, MODE_DEATHSQUAD)
auto_recall_shuttle = 1
ert_disabled = 1
require_all_templates = 1
votable = 0

View File

@@ -1,12 +1,12 @@
/datum/game_mode/infestation
name = "infestation"
round_description = "There's something in the walls!"
extended_round_description = "Two alien antagonists (Xenomorphs, Cortical Borers or Changelings) may spawn during this round."
extended_round_description = "Two alien antagonists (Cortical Borers or Changelings) spawn during this round."
config_tag = "infestation"
required_players = 15
required_enemies = 5
end_on_antag_death = 1
antag_tags = list(MODE_BORER, MODE_XENOMORPH, MODE_CHANGELING)
antag_tags = list(MODE_BORER, MODE_CHANGELING)
require_all_templates = 1
votable = 0

View File

@@ -1,209 +0,0 @@
// AI (i.e. game AI, not the AI player) controlled bots
/obj/machinery/bot
icon = 'icons/obj/aibots.dmi'
layer = MOB_LAYER
light_range = 3
use_power = 0
var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds"
var/on = 1
var/health = 0 //do not forget to set health for your bot!
var/maxhealth = 0
var/fire_dam_coeff = 1.0
var/brute_dam_coeff = 1.0
var/open = 0//Maint panel
var/locked = 1
//var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots
/obj/machinery/bot/proc/turn_on()
if(stat) return 0
on = 1
set_light(initial(light_range))
return 1
/obj/machinery/bot/proc/turn_off()
on = 0
set_light(0)
/obj/machinery/bot/proc/explode()
qdel(src)
/obj/machinery/bot/proc/healthcheck()
if (src.health <= 0)
src.explode()
/obj/machinery/bot/emag_act(var/remaining_charges, var/user)
if(locked && !emagged)
locked = 0
emagged = 1
user << "<span class='warning'>You short out [src]'s maintenance hatch lock.</span>"
log_and_message_admins("emagged [src]'s maintenance hatch lock")
return 1
if(!locked && open && emagged == 1)
emagged = 2
log_and_message_admins("emagged [src]'s inner circuits")
return 1
/obj/machinery/bot/examine(mob/user)
..(user)
if (src.health < maxhealth)
if (src.health > maxhealth/3)
user << "<span class='warning'>[src]'s parts look loose.</span>"
else
user << "<span class='danger'>[src]'s parts look very loose!</span>"
return
/obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/screwdriver))
if(!locked)
open = !open
user << "<span class='notice'>Maintenance panel is now [src.open ? "opened" : "closed"].</span>"
else if(istype(W, /obj/item/weapon/weldingtool))
if(health < maxhealth)
if(open)
health = min(maxhealth, health+10)
user.visible_message("<span class='warning'>[user] repairs [src]!</span>","<span class='notice'>You repair [src]!</span>")
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
if(hasvar(W,"force") && hasvar(W,"damtype"))
switch(W.damtype)
if("fire")
src.health -= W.force * fire_dam_coeff
if("brute")
src.health -= W.force * brute_dam_coeff
..()
healthcheck()
else
..()
/obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj)
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
return
health -= Proj.damage
..()
healthcheck()
/obj/machinery/bot/ex_act(severity)
switch(severity)
if(1.0)
src.explode()
return
if(2.0)
src.health -= rand(5,10)*fire_dam_coeff
src.health -= rand(10,20)*brute_dam_coeff
healthcheck()
return
if(3.0)
if (prob(50))
src.health -= rand(1,5)*fire_dam_coeff
src.health -= rand(1,5)*brute_dam_coeff
healthcheck()
return
return
/obj/machinery/bot/emp_act(severity)
var/was_on = on
stat |= EMPED
var/obj/effect/overlay/pulse2 = PoolOrNew(/obj/effect/overlay, src.loc )
pulse2.icon = 'icons/effects/effects.dmi'
pulse2.icon_state = "empdisable"
pulse2.name = "emp sparks"
pulse2.anchored = 1
pulse2.set_dir(pick(cardinal))
spawn(10)
qdel(pulse2)
if (on)
turn_off()
spawn(severity*300)
stat &= ~EMPED
if (was_on)
turn_on()
/obj/machinery/bot/attack_ai(mob/user as mob)
src.attack_hand(user)
/obj/machinery/bot/attack_hand(var/mob/living/carbon/human/user)
if(!istype(user))
return ..()
if(user.species.can_shred(user))
src.health -= rand(15,30)*brute_dam_coeff
src.visible_message("<span class='danger'>[user] has slashed [src]!</span>")
playsound(src.loc, 'sound/weapons/slice.ogg', 25, 1, -1)
if(prob(10))
new /obj/effect/decal/cleanable/blood/oil(src.loc)
healthcheck()
/******************************************************************/
// Navigation procs
// Used for A-star pathfinding
// Returns the surrounding cardinal turfs with open links
// Including through doors openable with the ID
/turf/proc/CardinalTurfsWithAccess(var/obj/item/weapon/card/id/ID)
var/L[] = new()
// for(var/turf/simulated/t in oview(src,1))
for(var/d in cardinal)
var/turf/simulated/T = get_step(src, d)
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
// Returns true if a link between A and B is blocked
// Movement through doors allowed if ID has access
/proc/LinkBlockedWithAccess(turf/A, turf/B, obj/item/weapon/card/id/ID)
if(A == null || B == null) return 1
var/adir = get_dir(A,B)
var/rdir = get_dir(B,A)
if((adir & (NORTH|SOUTH)) && (adir & (EAST|WEST))) // diagonal
var/iStep = get_step(A,adir&(NORTH|SOUTH))
if(!LinkBlockedWithAccess(A,iStep, ID) && !LinkBlockedWithAccess(iStep,B,ID))
return 0
var/pStep = get_step(A,adir&(EAST|WEST))
if(!LinkBlockedWithAccess(A,pStep,ID) && !LinkBlockedWithAccess(pStep,B,ID))
return 0
return 1
if(DirBlockedWithAccess(A,adir, ID))
return 1
if(DirBlockedWithAccess(B,rdir, ID))
return 1
for(var/obj/O in B)
if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER))
return 1
return 0
// Returns true if direction is blocked from loc
// Checks doors against access with given ID
/proc/DirBlockedWithAccess(turf/loc,var/dir,var/obj/item/weapon/card/id/ID)
for(var/obj/structure/window/D in loc)
if(!D.density) continue
if(D.dir == SOUTHWEST) return 1
if(D.dir == dir) return 1
for(var/obj/machinery/door/D in loc)
if(!D.density) continue
if(istype(D, /obj/machinery/door/window))
if( dir & D.dir ) return !D.check_access(ID)
//if((dir & SOUTH) && (D.dir & (EAST|WEST))) return !D.check_access(ID)
//if((dir & EAST ) && (D.dir & (NORTH|SOUTH))) return !D.check_access(ID)
else return !D.check_access(ID) // it's a real, air blocking door
return 0

View File

@@ -1,887 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
// Mulebot - carries crates around for Quartermaster
// Navigates via floor navbeacons
// Remote Controlled from QM's PDA
/obj/machinery/bot/mulebot
name = "Mulebot"
desc = "A Multiple Utility Load Effector bot."
icon_state = "mulebot0"
layer = MOB_LAYER
density = 1
anchored = 1
animate_movement=1
health = 150 //yeah, it's tougher than ed209 because it is a big metal box with wheels --rastaf0
maxhealth = 150
fire_dam_coeff = 0.7
brute_dam_coeff = 0.5
var/atom/movable/load = null // the loaded crate (usually)
var/beacon_freq = 1400
var/control_freq = BOT_FREQ
suffix = ""
var/turf/target // this is turf to navigate to (location of beacon)
var/loaddir = 0 // this the direction to unload onto/load from
var/new_destination = "" // pending new destination (waiting for beacon response)
var/destination = "" // destination description
var/home_destination = "" // tag of home beacon
req_access = list(access_cargo) // added robotics access so assembly line drop-off works properly -veyveyr //I don't think so, Tim. You need to add it to the MULE's hidden robot ID card. -NEO
var/path[] = new()
var/mode = 0 //0 = idle/ready
//1 = loading/unloading
//2 = moving to deliver
//3 = returning to home
//4 = blocked
//5 = computing navigation
//6 = waiting for nav computation
//7 = no destination beacon found (or no route)
var/blockcount = 0 //number of times retried a blocked path
var/reached_target = 1 //true if already reached the target
var/refresh = 1 // true to refresh dialogue
var/auto_return = 1 // true if auto return to home beacon after unload
var/auto_pickup = 1 // true if auto-pickup at beacon
var/obj/item/weapon/cell/cell
// the installed power cell
// constants for internal wiring bitflags
var/datum/wires/mulebot/wires = null
var/bloodiness = 0 // count of bloodiness
/obj/machinery/bot/mulebot/New()
..()
wires = new(src)
botcard = new(src)
botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
cell = new(src)
cell.charge = 2000
cell.maxcharge = 2000
spawn(5) // must wait for map loading to finish
if(radio_controller)
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
var/count = 0
for(var/obj/machinery/bot/mulebot/other in world)
count++
if(!suffix)
suffix = "#[count]"
name = "Mulebot ([suffix])"
/obj/machinery/bot/mulebot/Destroy()
unload(0)
qdel(wires)
wires = null
if(radio_controller)
radio_controller.remove_object(src,beacon_freq)
radio_controller.remove_object(src,control_freq)
return ..()
// attack by item
// emag : lock/unlock,
// screwdriver: open/close hatch
// cell: insert it
// other: chance to knock rider off bot
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user)
if(istype(I,/obj/item/weapon/cell) && open && !cell)
var/obj/item/weapon/cell/C = I
user.drop_item()
C.loc = src
cell = C
updateDialog()
else if(istype(I,/obj/item/weapon/screwdriver))
if(locked)
user << "<span class='notice'>The maintenance hatch cannot be opened or closed while the controls are locked.</span>"
return
open = !open
if(open)
src.visible_message("[user] opens the maintenance hatch of [src]", "<span class='notice'>You open [src]'s maintenance hatch.</span>")
on = 0
icon_state="mulebot-hatch"
else
src.visible_message("[user] closes the maintenance hatch of [src]", "<span class='notice'>You close [src]'s maintenance hatch.</span>")
icon_state = "mulebot0"
updateDialog()
else if (istype(I, /obj/item/weapon/wrench))
if (src.health < maxhealth)
src.health = min(maxhealth, src.health+25)
user.visible_message(
"<span class='notice'>\The [user] repairs \the [src]!</span>",
"<span class='notice'>You repair \the [src]!</span>"
)
else
user << "<span class='notice'>[src] does not need a repair!</span>"
else if(load && ismob(load)) // chance to knock off rider
if(prob(1+I.force * 2))
unload(0)
user.visible_message("<span class='warning'>[user] knocks [load] off [src] with \the [I]!</span>", "<span class='warning'>You knock [load] off [src] with \the [I]!</span>")
else
user << "You hit [src] with \the [I] but to no effect."
else
..()
return
/obj/machinery/bot/mulebot/emag_act(var/remaining_charges, var/user)
locked = !locked
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
flick("mulebot-emagged", src)
playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0)
return 1
/obj/machinery/bot/mulebot/ex_act(var/severity)
unload(0)
switch(severity)
if(2)
BITRESET(wires, rand(0,9))
BITRESET(wires, rand(0,9))
BITRESET(wires, rand(0,9))
if(3)
BITRESET(wires, rand(0,9))
..()
return
/obj/machinery/bot/mulebot/bullet_act()
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))
src.visible_message("<span class='warning'>Something shorts out inside [src]!</span>")
var/index = 1<< (rand(0,9))
if(wires & index)
wires &= ~index
else
wires |= index
..()
/obj/machinery/bot/mulebot/attack_ai(var/mob/user)
user.set_machine(src)
interact(user, 1)
/obj/machinery/bot/mulebot/attack_hand(var/mob/user)
. = ..()
if (.)
return
user.set_machine(src)
interact(user, 0)
/obj/machinery/bot/mulebot/interact(var/mob/user, var/ai=0)
var/dat
dat += "<TT><B>Multiple Utility Load Effector Mk. III</B></TT><BR><BR>"
dat += "ID: [suffix]<BR>"
dat += "Power: [on ? "On" : "Off"]<BR>"
if(!open)
dat += "Status: "
switch(mode)
if(0)
dat += "Ready"
if(1)
dat += "Loading/Unloading"
if(2)
dat += "Navigating to Delivery Location"
if(3)
dat += "Navigating to Home"
if(4)
dat += "Waiting for clear path"
if(5,6)
dat += "Calculating navigation path"
if(7)
dat += "Unable to locate destination"
dat += "<BR>Current Load: [load ? load.name : "<i>none</i>"]<BR>"
dat += "Destination: [!destination ? "<i>none</i>" : destination]<BR>"
dat += "Power level: [cell ? cell.percent() : 0]%<BR>"
if(locked && !ai)
dat += "<HR>Controls are locked <A href='byond://?src=\ref[src];op=unlock'><I>(unlock)</I></A>"
else
dat += "<HR>Controls are unlocked <A href='byond://?src=\ref[src];op=lock'><I>(lock)</I></A><BR><BR>"
dat += "<A href='byond://?src=\ref[src];op=power'>Toggle Power</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=stop'>Stop</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=go'>Proceed</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=home'>Return to Home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=destination'>Set Destination</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=sethome'>Set Home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
dat += "<A href='byond://?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
if(load)
dat += "<A href='byond://?src=\ref[src];op=unload'>Unload Now</A><BR>"
dat += "<HR>The maintenance hatch is closed.<BR>"
else
if(!ai)
dat += "The maintenance hatch is open.<BR><BR>"
dat += "Power cell: "
if(cell)
dat += "<A href='byond://?src=\ref[src];op=cellremove'>Installed</A><BR>"
else
dat += "<A href='byond://?src=\ref[src];op=cellinsert'>Removed</A><BR>"
dat += wires.GetInteractWindow()
else
dat += "The bot is in maintenance mode and cannot be controlled.<BR>"
user << browse("<HEAD><TITLE>Mulebot [suffix ? "([suffix])" : ""]</TITLE></HEAD>[dat]", "window=mulebot;size=350x500")
onclose(user, "mulebot")
return
/obj/machinery/bot/mulebot/Topic(href, href_list)
if(..())
return
if (usr.stat)
return
if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
switch(href_list["op"])
if("lock", "unlock")
if(src.allowed(usr))
locked = !locked
updateDialog()
else
usr << "<span class='warning'>Access denied.</span>"
return
if("power")
if (src.on)
turn_off()
else if (cell && !open)
if (!turn_on())
usr << "<span class='warning'>You can't switch on [src].</span>"
return
else
return
visible_message("[usr] switches [on ? "on" : "off"] [src].")
updateDialog()
if("cellremove")
if(open && cell && !usr.get_active_hand())
cell.update_icon()
usr.put_in_active_hand(cell)
cell.add_fingerprint(usr)
cell = null
usr.visible_message("<span class='notice'>[usr] removes the power cell from [src].</span>", "<span class='notice'>You remove the power cell from [src].</span>")
updateDialog()
if("cellinsert")
if(open && !cell)
var/obj/item/weapon/cell/C = usr.get_active_hand()
if(istype(C))
usr.drop_item()
cell = C
C.loc = src
C.add_fingerprint(usr)
usr.visible_message("<span class='notice'>[usr] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
updateDialog()
if("stop")
if(mode >=2)
mode = 0
updateDialog()
if("go")
if(mode == 0)
start()
updateDialog()
if("home")
if(mode == 0 || mode == 2)
start_home()
updateDialog()
if("destination")
refresh=0
var/new_dest
var/list/beaconlist = new()
for(var/obj/machinery/navbeacon/N in navbeacons)
beaconlist.Add(N.location)
if(beaconlist.len)
new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) in beaconlist
else
alert("No destination beacons available.")
refresh=1
if(new_dest)
set_destination(new_dest)
if("setid")
refresh=0
var/new_id = sanitize(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null, MAX_NAME_LEN)
refresh=1
if(new_id)
suffix = new_id
name = "Mulebot ([suffix])"
updateDialog()
if("sethome")
refresh=0
var/new_home = input("Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) as text|null
refresh=1
if(new_home)
home_destination = new_home
updateDialog()
if("unload")
if(load && mode !=1)
if(loc == target)
unload(loaddir)
else
unload(0)
if("autoret")
auto_return = !auto_return
if("autopick")
auto_pickup = !auto_pickup
if("close")
usr.unset_machine()
usr << browse(null,"window=mulebot")
updateDialog()
//src.updateUsrDialog()
else
usr << browse(null, "window=mulebot")
usr.unset_machine()
return
// returns true if the bot has power
/obj/machinery/bot/mulebot/proc/has_power()
return !open && cell && cell.charge>0 && wires.HasPower()
// mousedrop a crate to load the bot
// can load anything if emagged
/obj/machinery/bot/mulebot/MouseDrop_T(var/atom/movable/C, mob/user)
if(user.stat)
return
if (!on || !istype(C)|| C.anchored || get_dist(user, src) > 1 || get_dist(src,C) > 1 )
return
if(load)
return
load(C)
// called to load a crate
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate))
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
return // if not emagged, only allow crates to be loaded
//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
return
if(!isturf(C.loc)) //To prevent the loading from stuff from someone's inventory, which wouldn't get handled properly.
return
if(get_dist(C, src) > 1 || load || !on)
return
for(var/obj/structure/plasticflaps/P in src.loc)//Takes flaps into account
if(!CanPass(C,P))
return
mode = 1
// if a create, close before loading
var/obj/structure/closet/crate/crate = C
if(istype(crate))
crate.close()
C.loc = src.loc
sleep(2)
if(C.loc != src.loc) //To prevent you from going onto more thano ne bot.
return
C.loc = src
load = C
C.pixel_y += 9
if(C.layer < layer)
C.layer = layer + 0.1
overlays += C
if(ismob(C))
var/mob/M = C
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
mode = 0
send_status()
// called to unload the bot
// argument is optional direction to unload
// if zero, unload at bot's location
/obj/machinery/bot/mulebot/proc/unload(var/dirn = 0)
if(!load)
return
mode = 1
overlays.Cut()
load.loc = src.loc
load.pixel_y -= 9
load.layer = initial(load.layer)
if(ismob(load))
var/mob/M = load
if(M.client)
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
if(dirn)
var/turf/T = src.loc
T = get_step(T,dirn)
if(CanPass(load,T))//Can't get off onto anything that wouldn't let you pass normally
step(load, dirn)
else
load.loc = src.loc//Drops you right there, so you shouldn't be able to get yourself stuck
load = null
// in case non-load items end up in contents, dump every else too
// this seems to happen sometimes due to race conditions
// with items dropping as mobs are loaded
for(var/atom/movable/AM in src)
if(AM == cell || AM == botcard) continue
AM.loc = src.loc
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
if(ismob(AM))
var/mob/M = AM
if(M.client)
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
mode = 0
/obj/machinery/bot/mulebot/process()
if(!has_power())
on = 0
return
if(on)
var/speed = (wires.Motor1() ? 1:0) + (wires.Motor2() ? 2:0)
//world << "speed: [speed]"
switch(speed)
if(0)
// do nothing
if(1)
process_bot()
spawn(2)
process_bot()
sleep(2)
process_bot()
sleep(2)
process_bot()
sleep(2)
process_bot()
if(2)
process_bot()
spawn(4)
process_bot()
if(3)
process_bot()
if(refresh) updateDialog()
/obj/machinery/bot/mulebot/proc/process_bot()
//if(mode) world << "Mode: [mode]"
switch(mode)
if(0) // idle
icon_state = "mulebot0"
return
if(1) // loading/unloading
return
if(2,3,4) // navigating to deliver,home, or blocked
if(loc == target) // reached target
at_target()
return
else if(path.len > 0 && target) // valid path
var/turf/next = path[1]
reached_target = 0
if(next == loc)
path -= next
return
if(istype( next, /turf/simulated))
//world << "at ([x],[y]) moving to ([next.x],[next.y])"
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.set_dir(newdir)
else
newdir = newdir | dir
if(newdir == 3)
newdir = 1
else if(newdir == 12)
newdir = 4
B.set_dir(newdir)
bloodiness--
var/moved = step_towards(src, next) // attempt to move
if(cell) cell.use(1)
if(moved) // successful move
//world << "Successful move."
blockcount = 0
path -= loc
if(mode==4)
spawn(1)
send_status()
if(destination == home_destination)
mode = 3
else
mode = 2
else // failed to move
//world << "Unable to move."
blockcount++
mode = 4
if(blockcount == 3)
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(blockcount > 5) // attempt 5 times before recomputing
// find new path excluding blocked turf
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
spawn(2)
calc_path(next)
if(path.len > 0)
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
mode = 4
mode =6
return
return
else
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
//world << "Bad turf."
mode = 5
return
else
//world << "No path."
mode = 5
return
if(5) // calculate new path
//world << "Calc new path."
mode = 6
spawn(0)
calc_path()
if(path.len > 0)
blockcount = 0
mode = 4
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
else
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
mode = 7
//if(6)
//world << "Pending path calc."
//if(7)
//world << "No dest / no route."
return
// calculates a path to the current destination
// given an optional turf to avoid
/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid)
if(!src.path)
src.path = list()
// sets the current destination
// signals all beacons matching the delivery code
// beacons will return a signal giving their locations
/obj/machinery/bot/mulebot/proc/set_destination(var/new_dest)
spawn(0)
new_destination = new_dest
post_signal(beacon_freq, "findbeacon", "delivery")
updateDialog()
// starts bot moving to current destination
/obj/machinery/bot/mulebot/proc/start()
if(destination == home_destination)
mode = 3
else
mode = 2
icon_state = "mulebot[wires.MobAvoid()]"
// starts bot moving to home
// sends a beacon query to find
/obj/machinery/bot/mulebot/proc/start_home()
spawn(0)
set_destination(home_destination)
mode = 4
icon_state = "mulebot[wires.MobAvoid()]"
// called when bot reaches current target
/obj/machinery/bot/mulebot/proc/at_target()
if(!reached_target)
src.visible_message("[src] makes a chiming sound!", "You hear a chime.")
playsound(src.loc, 'sound/machines/chime.ogg', 50, 0)
reached_target = 1
if(load) // if loaded, unload at target
unload(loaddir)
else
// not loaded
if(auto_pickup) // find a crate
var/atom/movable/AM
if(!wires.LoadCheck()) // if emagged, load first unanchored thing we find
for(var/atom/movable/A in get_step(loc, loaddir))
if(!A.anchored)
AM = A
break
else // otherwise, look for crates only
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
if(AM)
load(AM)
// whatever happened, check to see if we return home
if(auto_return && destination != home_destination)
// auto return set and not at home already
start_home()
mode = 4
else
mode = 0 // otherwise go idle
send_status() // report status to anyone listening
return
// called when bot bumps into anything
/obj/machinery/bot/mulebot/Bump(var/atom/obs)
if(!wires.MobAvoid()) //usually just bumps, but if avoidance disabled knock over mobs
var/mob/M = obs
if(ismob(M))
if(istype(M,/mob/living/silicon/robot))
src.visible_message("<span class='warning'>[src] bumps into [M]!</span>")
else
src.visible_message("<span class='warning'>[src] knocks over [M]!</span>")
M.stop_pulling()
M.Stun(8)
M.Weaken(5)
M.lying = 1
..()
// called from mob/living/carbon/human/Crossed()
// when mulebot is in the same loc
/obj/machinery/bot/mulebot/proc/RunOver(var/mob/living/carbon/human/H)
src.visible_message("<span class='warning'>[src] drives over [H]!</span>")
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
var/damage = rand(5,15)
H.apply_damage(2*damage, BRUTE, BP_HEAD)
H.apply_damage(2*damage, BRUTE, BP_TORSO)
H.apply_damage(0.5*damage, BRUTE, BP_L_LEG)
H.apply_damage(0.5*damage, BRUTE, BP_R_LEG)
H.apply_damage(0.5*damage, BRUTE, BP_L_ARM)
H.apply_damage(0.5*damage, BRUTE, BP_R_ARM)
blood_splatter(src,H,1)
bloodiness += 4
// player on mulebot attempted to move
/obj/machinery/bot/mulebot/relaymove(var/mob/user)
if(user.stat)
return
if(load == user)
unload(0)
return
// receive a radio signal
// used for control and beacon reception
/obj/machinery/bot/mulebot/receive_signal(datum/signal/signal)
if(!on)
return
var/recv = signal.data["command"]
// process all-bot input
if(recv=="bot_status" && wires.RemoteRX())
send_status()
recv = signal.data["command [suffix]"]
if(wires.RemoteRX())
// process control input
switch(recv)
if("stop")
mode = 0
return
if("go")
start()
return
if("target")
set_destination(signal.data["destination"] )
return
if("unload")
if(loc == target)
unload(loaddir)
else
unload(0)
return
if("home")
start_home()
return
if("bot_status")
send_status()
return
if("autoret")
auto_return = text2num(signal.data["value"])
return
if("autopick")
auto_pickup = text2num(signal.data["value"])
return
// receive response from beacon
recv = signal.data["beacon"]
if(wires.BeaconRX())
if(recv == new_destination) // if the recvd beacon location matches the set destination
// the we will navigate there
destination = new_destination
target = signal.source.loc
var/direction = signal.data["dir"] // this will be the load/unload dir
if(direction)
loaddir = text2num(direction)
else
loaddir = 0
icon_state = "mulebot[wires.MobAvoid()]"
calc_path()
updateDialog()
// send a radio signal with a single data key/value pair
/obj/machinery/bot/mulebot/proc/post_signal(var/freq, var/key, var/value)
post_signal_multiple(freq, list("[key]" = value) )
// send a radio signal with multiple data key/values
/obj/machinery/bot/mulebot/proc/post_signal_multiple(var/freq, var/list/keyval)
if(freq == beacon_freq && !wires.BeaconRX())
return
if(freq == control_freq && !wires.RemoteTX())
return
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
if(!frequency) return
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
//for(var/key in keyval)
// signal.data[key] = keyval[key]
signal.data = keyval
//world << "sent [key],[keyval[key]] on [freq]"
if (signal.data["findbeacon"])
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
else if (signal.data["type"] == "mulebot")
frequency.post_signal(src, signal, filter = RADIO_MULEBOT)
else
frequency.post_signal(src, signal)
// signals bot status etc. to controller
/obj/machinery/bot/mulebot/proc/send_status()
var/list/kv = list(
"type" = "mulebot",
"name" = suffix,
"loca" = (loc ? loc.loc : "Unknown"), // somehow loc can be null and cause a runtime - Quarxink
"mode" = mode,
"powr" = (cell ? cell.percent() : 0),
"dest" = destination,
"home" = home_destination,
"load" = load,
"retn" = auto_return,
"pick" = auto_pickup,
)
post_signal_multiple(control_freq, kv)
/obj/machinery/bot/mulebot/emp_act(severity)
if (cell)
cell.emp_act(severity)
if(load)
load.emp_act(severity)
..()
/obj/machinery/bot/mulebot/explode()
src.visible_message("<span class='danger'>[src] blows apart!</span>", 1)
var/turf/Tsec = get_turf(src)
new /obj/item/device/assembly/prox_sensor(Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
new /obj/item/stack/cable_coil/cut(Tsec)
if (cell)
cell.loc = Tsec
cell.update_icon()
cell = null
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
new /obj/effect/decal/cleanable/blood/oil(src.loc)
unload(0)
qdel(src)

View File

@@ -41,13 +41,13 @@
if(scan)
usr << "You remove \the [scan] from \the [src]."
scan.loc = get_turf(src)
scan.forceMove(get_turf(src))
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
usr.put_in_hands(scan)
scan = null
else if(modify)
usr << "You remove \the [modify] from \the [src]."
modify.loc = get_turf(src)
modify.forceMove(get_turf(src))
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
usr.put_in_hands(modify)
modify = null
@@ -60,10 +60,12 @@
return ..()
if(!scan && (access_change_ids in id_card.access) && user.unEquip(id_card))
id_card.loc = src
user.drop_item()
id_card.forceMove(src)
scan = id_card
else if(!modify)
id_card.loc = src
user.drop_item()
id_card.forceMove(src)
modify = id_card
nanomanager.update_uis(src)
@@ -146,34 +148,34 @@
data_core.manifest_modify(modify.registered_name, modify.assignment)
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
if(ishuman(usr))
modify.loc = usr.loc
modify.forceMove(get_turf(src))
if(!usr.get_active_hand())
usr.put_in_hands(modify)
modify = null
else
modify.loc = loc
modify.forceMove(get_turf(src))
modify = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.loc = src
I.forceMove(src)
modify = I
if ("scan")
if (scan)
if(ishuman(usr))
scan.loc = usr.loc
scan.forceMove(get_turf(src))
if(!usr.get_active_hand())
usr.put_in_hands(scan)
scan = null
else
scan.loc = src.loc
scan.forceMove(get_turf(src))
scan = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
I.forceMove(src)
scan = I
if("access")

View File

@@ -103,13 +103,6 @@
bumpopen(M)
return
if(istype(AM, /obj/machinery/bot))
var/obj/machinery/bot/bot = AM
if(src.check_access(bot.botcard))
if(density)
open()
return
if(istype(AM, /mob/living/bot))
var/mob/living/bot/bot = AM
if(src.check_access(bot.botcard))

View File

@@ -502,7 +502,7 @@ var/list/turret_icons
if(isanimal(L) || issmall(L)) // Animals are not so dangerous
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
if(isxenomorph(L) || isalien(L)) // Xenos are dangerous
if(isalien(L)) // Xenos are dangerous
return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET
if(ishuman(L)) //if the target is a human, analyze threat level

View File

@@ -1,440 +0,0 @@
/* Alien Effects!
* Contains:
* effect/alien
* Resin
* Weeds
* Acid
* Egg
*/
/*
* effect/alien
*/
/obj/effect/alien
name = "alien thing"
desc = "theres something alien about this"
icon = 'icons/mob/alien.dmi'
/*
* Resin
*/
/obj/effect/alien/resin
name = "resin"
desc = "Looks like some kind of slimy growth."
icon_state = "resin"
density = 1
opacity = 1
anchored = 1
var/health = 200
//var/mob/living/affecting = null
/obj/effect/alien/resin/wall
name = "resin wall"
desc = "Purple slime solidified into a wall."
icon_state = "resinwall" //same as resin, but consistency ho!
/obj/effect/alien/resin/membrane
name = "resin membrane"
desc = "Purple slime just thin enough to let light pass through."
icon_state = "resinmembrane"
opacity = 0
health = 120
/obj/effect/alien/resin/New()
..()
var/turf/T = get_turf(src)
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/effect/alien/resin/Destroy()
var/turf/T = get_turf(src)
T.thermal_conductivity = initial(T.thermal_conductivity)
..()
/obj/effect/alien/resin/proc/healthcheck()
if(health <=0)
density = 0
qdel(src)
return
/obj/effect/alien/resin/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
return
/obj/effect/alien/resin/ex_act(severity)
switch(severity)
if(1.0)
health-=50
if(2.0)
health-=50
if(3.0)
if (prob(50))
health-=50
else
health-=25
healthcheck()
return
/obj/effect/alien/resin/hitby(AM as mob|obj)
..()
for(var/mob/O in viewers(src, null))
O.show_message("<span class='danger'>[src] was hit by [AM].</span>", 1)
var/tforce = 0
if(ismob(AM))
tforce = 10
else
tforce = AM:throwforce
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
health = max(0, health - tforce)
healthcheck()
..()
return
/obj/effect/alien/resin/attack_hand()
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if (HULK in usr.mutations)
usr << "<span class='notice'>You easily destroy the [name].</span>"
for(var/mob/O in oviewers(src))
O.show_message("<span class='warning'>[usr] destroys the [name]!</span>", 1)
health = 0
else
// Aliens can get straight through these.
if(istype(usr,/mob/living/carbon))
var/mob/living/carbon/M = usr
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
for(var/mob/O in oviewers(src))
O.show_message("<span class='warning'>[usr] strokes the [name] and it melts away!</span>", 1)
health = 0
healthcheck()
return
usr << "<span class='notice'>You claw at the [name].</span>"
for(var/mob/O in oviewers(src))
O.show_message("<span class='warning'>[usr] claws at the [name]!</span>", 1)
health -= rand(5,10)
healthcheck()
return
/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
var/aforce = W.force
health = max(0, health - aforce)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
healthcheck()
..()
return
/obj/effect/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group) return 0
if(istype(mover) && mover.checkpass(PASSGLASS))
return !opacity
return !density
/*
* Weeds
*/
#define NODERANGE 3
/obj/effect/alien/weeds
name = "weeds"
desc = "Weird purple weeds."
icon_state = "weeds"
anchored = 1
density = 0
layer = 2
var/health = 15
var/obj/effect/alien/weeds/node/linked_node = null
/obj/effect/alien/weeds/node
icon_state = "weednode"
name = "purple sac"
desc = "Weird purple octopus-like thing."
layer = 3
light_range = NODERANGE
var/node_range = NODERANGE
/obj/effect/alien/weeds/node/New()
..(src.loc, src)
/obj/effect/alien/weeds/New(pos, node)
..()
if(istype(loc, /turf/space))
qdel(src)
return
linked_node = node
if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
spawn(rand(150, 200))
if(src)
Life()
return
/obj/effect/alien/weeds/proc/Life()
set background = 1
var/turf/U = get_turf(src)
/*
if (locate(/obj/movable, U))
U = locate(/obj/movable, U)
if(U.density == 1)
qdel(src)
return
Alien plants should do something if theres a lot of poison
if(U.poison> 200000)
health -= round(U.poison/200000)
update()
return
*/
if (istype(U, /turf/space))
qdel(src)
return
if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
return
direction_loop:
for(var/dirn in cardinal)
var/turf/T = get_step(src, dirn)
if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
continue
// if (locate(/obj/movable, T)) // don't propogate into movables
// continue
for(var/obj/O in T)
if(O.density)
continue direction_loop
PoolOrNew(/obj/effect/alien/weeds, T, linked_node)
/obj/effect/alien/weeds/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(3.0)
if (prob(5))
qdel(src)
return
/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(W.attack_verb.len)
visible_message("<span class='danger'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
else
visible_message("<span class='danger'>\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user))
damage = 15
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
health -= damage
healthcheck()
/obj/effect/alien/weeds/proc/healthcheck()
if(health <= 0)
qdel(src)
/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
#undef NODERANGE
/*
* Acid
*/
/obj/effect/alien/acid
name = "acid"
desc = "Burbling corrossive stuff. I wouldn't want to touch it."
icon_state = "acid"
density = 0
opacity = 0
anchored = 1
var/atom/target
var/ticks = 0
var/target_strength = 0
/obj/effect/alien/acid/New(loc, target)
..(loc)
src.target = target
if(isturf(target)) // Turf take twice as long to take down.
target_strength = 8
else
target_strength = 4
tick()
/obj/effect/alien/acid/proc/tick()
if(!target)
qdel(src)
ticks += 1
if(ticks >= target_strength)
for(var/mob/O in hearers(src, null))
O.show_message("<span class='alium'>[src.target] collapses under its own weight into a puddle of goop and undigested debris!</span>", 1)
if(istype(target, /turf/simulated/wall)) // I hate turf code.
var/turf/simulated/wall/W = target
W.dismantle_wall(1)
else
qdel(target)
qdel(src)
return
switch(target_strength - ticks)
if(6)
visible_message("<span class='alium'>[src.target] is holding up against the acid!</span>")
if(4)
visible_message("<span class='alium'>[src.target]\s structure is being melted by the acid!</span>")
if(2)
visible_message("<span class='alium'>[src.target] is struggling to withstand the acid!</span>")
if(0 to 1)
visible_message("<span class='alium'>[src.target] begins to crumble under the acid!</span>")
spawn(rand(150, 200)) tick()
/*
* Egg
*/
/var/const //for the status var
BURST = 0
BURSTING = 1
GROWING = 2
GROWN = 3
MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger
MAX_GROWTH_TIME = 3000
/obj/effect/alien/egg
desc = "It looks like a weird egg"
name = "egg"
icon_state = "egg_growing"
density = 0
anchored = 1
var/health = 100
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
flags = PROXMOVE
/obj/effect/alien/egg/New()
if(config.aliens_allowed)
..()
spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
Grow()
else
qdel(src)
/obj/effect/alien/egg/attack_hand(user as mob)
var/mob/living/carbon/M = user
if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs))
return attack_hand(user)
switch(status)
if(BURST)
user << "<span class='warning'>You clear the hatched egg.</span>"
qdel(src)
return
if(GROWING)
user << "<span class='warning'>The child is not developed yet.</span>"
return
if(GROWN)
user << "<span class='warning'>You retrieve the child.</span>"
Burst(0)
return
/obj/effect/alien/egg/proc/GetFacehugger()
return locate(/obj/item/clothing/mask/facehugger) in contents
/obj/effect/alien/egg/proc/Grow()
icon_state = "egg"
status = GROWN
new /obj/item/clothing/mask/facehugger(src)
return
/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
if(status == GROWN || status == GROWING)
var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
icon_state = "egg_hatched"
flick("egg_opening", src)
status = BURSTING
spawn(15)
status = BURST
child.loc = get_turf(src)
if(kill && istype(child))
child.Die()
else
for(var/mob/M in range(1,src))
if(CanHug(M))
child.Attach(M)
break
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
return
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
if(health <= 0)
return
if(W.attack_verb.len)
src.visible_message("<span class='danger'>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
else
src.visible_message("<span class='danger'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user))
damage = 15
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
src.health -= damage
src.healthcheck()
/obj/effect/alien/egg/proc/healthcheck()
if(health <= 0)
Burst()
/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 500 + T0C)
health -= 5
healthcheck()
/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
if(status == GROWN)
if(!CanHug(AM))
return
var/mob/living/carbon/C = AM
if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST)
return
Burst(0)

View File

@@ -424,8 +424,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
cartdata["radio"] = 1
if(istype(cartridge.radio, /obj/item/radio/integrated/signal))
cartdata["radio"] = 2
if(istype(cartridge.radio, /obj/item/radio/integrated/mule))
cartdata["radio"] = 3
//if(istype(cartridge.radio, /obj/item/radio/integrated/mule))
// cartdata["radio"] = 3
if(mode == 2)
cartdata["charges"] = cartridge.charges ? cartridge.charges : 0

View File

@@ -124,10 +124,6 @@
icon_state = "cart-q"
access_quartermaster = 1
/obj/item/weapon/cartridge/quartermaster/initialize()
radio = new /obj/item/radio/integrated/mule(src)
..()
/obj/item/weapon/cartridge/head
name = "\improper Easy-Record DELUXE"
icon_state = "cart-h"
@@ -141,9 +137,6 @@
access_janitor = 1
access_security = 1
/obj/item/weapon/cartridge/hop/initialize()
radio = new /obj/item/radio/integrated/mule(src)
/obj/item/weapon/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE"
icon_state = "cart-hos"
@@ -351,40 +344,26 @@
/* MULEBOT Control (Mode: 48) */
if(mode==48)
var/muleData[0]
var/mulebotsData[0]
if(istype(radio,/obj/item/radio/integrated/mule))
var/obj/item/radio/integrated/mule/QC = radio
muleData["active"] = QC.active
if(QC.active && !isnull(QC.botstatus))
var/area/loca = QC.botstatus["loca"]
var/loca_name = sanitize(loca.name)
muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"]))
var/count = 0
else
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
for(var/mob/living/bot/mulebot/M in living_mob_list)
if(!M.on)
continue
++count
var/muleData[0]
muleData["name"] = M.suffix
muleData["location"] = get_area(M)
muleData["mode"] = M.mode
muleData["home"] = M.homeName
muleData["target"] = M.targetName
muleData["ref"] = "\ref[M]"
muleData["load"] = M.load ? M.load.name : "Nothing"
mulebotsData[++mulebotsData.len] = muleData.Copy()
var/mulebotsCount=0
for(var/obj/machinery/bot/B in QC.botlist)
mulebotsCount++
if(B.loc)
mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]")
if(!mulebotsData.len)
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
muleData["bots"] = mulebotsData
muleData["count"] = mulebotsCount
else
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
muleData["active"] = 0
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
muleData["bots"] = mulebotsData
muleData["count"] = 0
values["mulebot"] = muleData
values["mulebotcount"] = count
values["mulebots"] = mulebotsData
@@ -575,5 +554,9 @@
loc:mode = 43
mode = 43
if("MULEbot")
var/mob/living/bot/mulebot/M = locate(href_list["ref"])
if(istype(M))
M.obeyCommand(href_list["command"])
return 1

View File

@@ -105,107 +105,6 @@
radio_controller.remove_object(src, control_freq)
..()
/obj/item/radio/integrated/mule
var/list/botlist = null // list of bots
var/obj/machinery/bot/mulebot/active // the active bot; if null, show bot list
var/list/botstatus // the status signal sent by the bot
var/list/beacons
var/beacon_freq = 1400
var/control_freq = BOT_FREQ
// create a new QM cartridge, and register to receive bot control & beacon message
New()
..()
spawn(5)
if(radio_controller)
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
spawn(10)
post_signal(beacon_freq, "findbeacon", "delivery", s_filter = RADIO_NAVBEACONS)
// receive radio signals
// can detect bot status signals
// and beacon locations
// create/populate lists as they are recvd
receive_signal(datum/signal/signal)
// var/obj/item/device/pda/P = src.loc
/*
world << "recvd:[P] : [signal.source]"
for(var/d in signal.data)
world << "- [d] = [signal.data[d]]"
*/
if(signal.data["type"] == "mulebot")
if(!botlist)
botlist = new()
if(!(signal.source in botlist))
botlist += signal.source
if(active == signal.source)
var/list/b = signal.data
botstatus = b.Copy()
else if(signal.data["beacon"])
if(!beacons)
beacons = new()
beacons[signal.data["beacon"] ] = signal.source
// if(istype(P)) P.updateSelfDialog()
Topic(href, href_list)
..()
var/cmd = "command"
if(active) cmd = "command [active.suffix]"
switch(href_list["op"])
if("control")
active = locate(href_list["bot"])
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("scanbots") // find all bots
botlist = null
post_signal(control_freq, "command", "bot_status", s_filter = RADIO_MULEBOT)
if("botlist")
active = null
if("unload")
post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("setdest")
if(beacons)
var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in beacons
if(dest)
post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("retoff")
post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("reton")
post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("pickoff")
post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("pickon")
post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
if("stop", "go", "home")
post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
/*
* Radio Cartridge, essentially a signaler.
*/

View File

@@ -56,12 +56,6 @@
new /obj/item/clothing/mask/breath( src )
new /obj/item/weapon/tank/emergency_oxygen( src )
/obj/item/weapon/storage/box/vox/
New()
..()
new /obj/item/clothing/mask/breath( src )
new /obj/item/weapon/tank/emergency_nitrogen( src )
/obj/item/weapon/storage/box/engineer/
New()
..()

View File

@@ -132,6 +132,7 @@
name = "surgery kit"
desc = "Contains tools for surgery."
storage_slots = 10
max_storage_space = 23
/obj/item/weapon/storage/firstaid/surgery/New()
..()
@@ -302,4 +303,4 @@
new /obj/item/weapon/reagent_containers/pill/citalopram( src )
new /obj/item/weapon/reagent_containers/pill/citalopram( src )
new /obj/item/weapon/reagent_containers/pill/citalopram( src )
new /obj/item/weapon/reagent_containers/pill/citalopram( src )
new /obj/item/weapon/reagent_containers/pill/citalopram( src )

View File

@@ -148,31 +148,6 @@
gauge_icon = "indicator_emergency_double"
volume = 10
/obj/item/weapon/tank/emergency_nitrogen
name = "emergency nitrogen tank"
desc = "An emergency air tank hastily painted red and issued to Vox crewmembers."
icon_state = "emergency_nitro"
gauge_icon = "indicator_emergency"
gauge_cap = 4
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = 2.0
force = 4.0
distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
volume = 2
New()
..()
src.air_contents.adjust_gas("nitrogen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
examine(mob/user)
if(..(user, 0) && air_contents.gas["nitrogen"] < 0.2 && loc==user)
user << text("<span class='danger'>The meter on \the [src] indicates you are almost out of air!</span>")
user << sound('sound/effects/alert.ogg')
/*
* Nitrogen
*/

View File

@@ -51,6 +51,10 @@
for(var/i = 1;i<=held_count;i++)
new held_type(src)
/obj/structure/largecrate/animal/mulebot
name = "Mulebot crate"
held_type = /mob/living/bot/mulebot
/obj/structure/largecrate/animal/corgi
name = "corgi carrier"
held_type = /mob/living/simple_animal/corgi

View File

@@ -1,87 +0,0 @@
/obj/structure/lamarr
name = "lab cage"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "labcage1"
desc = "A glass lab container for storing interesting creatures."
density = 1
anchored = 1
unacidable = 1//Dissolving the case would also delete Lamarr
var/health = 30
var/occupied = 1
var/destroyed = 0
/obj/structure/lamarr/ex_act(severity)
switch(severity)
if (1)
new /obj/item/weapon/material/shard( src.loc )
Break()
qdel(src)
if (2)
if (prob(50))
src.health -= 15
src.healthcheck()
if (3)
if (prob(50))
src.health -= 5
src.healthcheck()
/obj/structure/lamarr/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
src.healthcheck()
return
/obj/structure/lamarr/proc/healthcheck()
if (src.health <= 0)
if (!( src.destroyed ))
src.density = 0
src.destroyed = 1
new /obj/item/weapon/material/shard( src.loc )
playsound(src, "shatter", 70, 1)
Break()
else
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
return
/obj/structure/lamarr/update_icon()
if(src.destroyed)
src.icon_state = "labcageb[src.occupied]"
else
src.icon_state = "labcage[src.occupied]"
return
/obj/structure/lamarr/attackby(obj/item/weapon/W as obj, mob/user as mob)
src.health -= W.force
src.healthcheck()
..()
return
/obj/structure/lamarr/attack_hand(mob/user as mob)
if (src.destroyed)
return
else
usr << "<span class='notice'>You kick the lab cage.</span>"
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
O << "<span class='warning'>[usr] kicks the lab cage.</span>"
src.health -= 2
healthcheck()
return
/obj/structure/lamarr/proc/Break()
if(occupied)
new /obj/item/clothing/mask/facehugger/lamarr(src.loc)
occupied = 0
update_icon()
return
/obj/item/clothing/mask/facehugger/lamarr
name = "Lamarr"
desc = "The worst she might do is attempt to... couple with your head."//hope we don't get sued over a harmless reference, rite?
sterile = 1
gender = FEMALE
/obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled
return

View File

@@ -30,7 +30,7 @@
/obj/structure/mirror/bullet_act(var/obj/item/projectile/Proj)
if(prob(Proj.get_structure_damage() * 2))
if(!shattered)
shatter()
@@ -63,31 +63,3 @@
else
user.visible_message("<span class='danger'>[user] hits [src] and bounces off!</span>")
return 1
// The following mirror is ~special~.
/obj/structure/mirror/raider
name = "cracked mirror"
desc = "Something seems strange about this old, dirty mirror. Your reflection doesn't look like you remember it."
icon_state = "mirror_broke"
shattered = 1
/obj/structure/mirror/raider/attack_hand(var/mob/living/carbon/human/user)
if(istype(get_area(src),/area/syndicate_mothership))
if(istype(user) && user.mind && user.mind.special_role == "Raider" && user.species.name != "Vox" && is_alien_whitelisted(user, "Vox"))
var/choice = input("Do you wish to become a true Vox of the Shoal? This is not reversible.") as null|anything in list("No","Yes")
if(choice && choice == "Yes")
var/mob/living/carbon/human/vox/vox = new(get_turf(src),"Vox")
vox.gender = user.gender
raiders.equip(vox)
if(user.mind)
user.mind.transfer_to(vox)
spawn(1)
var/newname = sanitizeSafe(input(vox,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
if(!newname || newname == "")
var/datum/language/L = all_languages[vox.species.default_language]
newname = L.get_random_name()
vox.real_name = newname
vox.name = vox.real_name
raiders.update_access(vox)
qdel(user)
..()

View File

@@ -1,86 +0,0 @@
//Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to.
#define NEST_RESIST_TIME 1200
/obj/structure/bed/nest
name = "alien nest"
desc = "It's a gruesome pile of thick, sticky resin shaped like a nest."
icon = 'icons/mob/alien.dmi'
icon_state = "nest"
var/health = 100
/obj/structure/bed/nest/update_icon()
return
/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob)
if(buckled_mob)
if(buckled_mob.buckled == src)
if(buckled_mob != user)
buckled_mob.visible_message(\
"<span class='notice'>[user.name] pulls [buckled_mob.name] free from the sticky nest!</span>",\
"<span class='notice'>[user.name] pulls you free from the gelatinous resin.</span>",\
"<span class='notice'>You hear squelching...</span>")
buckled_mob.pixel_y = 0
buckled_mob.old_y = 0
unbuckle_mob()
else
if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME)
return
buckled_mob.last_special = world.time
buckled_mob.visible_message(\
"<span class='warning'>[buckled_mob.name] struggles to break free of the gelatinous resin...</span>",\
"<span class='warning'>You struggle to break free from the gelatinous resin...</span>",\
"<span class='notice'>You hear squelching...</span>")
spawn(NEST_RESIST_TIME)
if(user && buckled_mob && user.buckled == src)
buckled_mob.last_special = world.time
buckled_mob.pixel_y = 0
buckled_mob.old_y = 0
unbuckle_mob()
src.add_fingerprint(user)
return
/obj/structure/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob)
if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) )
return
unbuckle_mob()
var/mob/living/carbon/xenos = user
var/mob/living/carbon/victim = M
if(istype(victim) && locate(/obj/item/organ/internal/xenos/hivenode) in victim.internal_organs)
return
if(istype(xenos) && !(locate(/obj/item/organ/internal/xenos/hivenode) in xenos.internal_organs))
return
if(M == usr)
return
else
M.visible_message(\
"<span class='notice'>[user.name] secretes a thick vile goo, securing [M.name] into [src]!</span>",\
"<span class='warning'>[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!</span>",\
"<span class='notice'>You hear squelching...</span>")
M.buckled = src
M.loc = src.loc
M.set_dir(src.dir)
M.update_canmove()
M.pixel_y = 6
M.old_y = 6
src.buckled_mob = M
src.add_fingerprint(user)
return
/obj/structure/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/aforce = W.force
health = max(0, health - aforce)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
for(var/mob/M in viewers(src, 7))
M.show_message("<span class='warning'>[user] hits [src] with [W]!</span>", 1)
healthcheck()
/obj/structure/bed/nest/proc/healthcheck()
if(health <=0)
density = 0
qdel(src)
return

View File

@@ -49,6 +49,7 @@ var/list/mechtoys = list(
layer = 4
explosion_resistance = 5
var/list/mobs_can_pass = list(
/mob/living/bot,
/mob/living/carbon/slime,
/mob/living/simple_animal/mouse,
/mob/living/silicon/robot/drone

View File

@@ -28,7 +28,7 @@
icon = 'icons/turf/floors.dmi'
icon_state = "plating"
/turf/simulated/shuttle/plating/vox //Skipjack plating
/turf/simulated/shuttle/plating/skipjack //Skipjack plating
oxygen = 0
nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD
@@ -36,7 +36,7 @@
name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle.
icon_state = "floor4"
/turf/simulated/shuttle/floor4/vox //skipjack floors
/turf/simulated/shuttle/floor4/skipjack //skipjack floors
name = "skipjack floor"
oxygen = 0
nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD

View File

@@ -37,9 +37,9 @@
..(newloc,"sandstone","diamond")
// Kind of wondering if this is going to bite me in the butt.
/turf/simulated/wall/voxshuttle/New(var/newloc)
..(newloc,"voxalloy")
/turf/simulated/wall/voxshuttle/attackby()
/turf/simulated/wall/skipjack/New(var/newloc)
..(newloc,"alienalloy")
/turf/simulated/wall/skipjack/attackby()
return
/turf/simulated/wall/titanium/New(var/newloc)
..(newloc,"titanium")

View File

@@ -86,7 +86,10 @@
msg += " - Playing"
if(C.is_afk())
msg += " (AFK)"
var/seconds = C.last_activity_seconds()
msg += " (AFK - "
msg += "[round(seconds / 60)] minutes, "
msg += "[seconds % 60] seconds)"
msg += "\n"
num_admins_online++
@@ -101,7 +104,10 @@
modmsg += " - Playing"
if(C.is_afk())
modmsg += " (AFK)"
var/seconds = C.last_activity_seconds()
modmsg += " (AFK - "
modmsg += "[round(seconds / 60)] minutes, "
modmsg += "[seconds % 60] seconds)"
modmsg += "\n"
num_mods_online++
@@ -115,7 +121,10 @@
mentmsg += " - Playing"
if(C.is_afk())
mentmsg += " (AFK)"
var/seconds = C.last_activity_seconds()
mentmsg += " (AFK - "
mentmsg += "[round(seconds / 60)] minutes, "
mentmsg += "[seconds % 60] seconds)"
mentmsg += "\n"
num_mentors_online++

View File

@@ -145,16 +145,10 @@ proc/admin_notice(var/message, var/rights)
body += {"<br><br>
<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>
<A href='?src=\ref[src];simplemake=observer;mob=\ref[M]'>Observer</A> |
\[ Xenos: <A href='?src=\ref[src];simplemake=larva;mob=\ref[M]'>Larva</A>
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Drone;mob=\ref[M]'>Drone</A>
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Hunter;mob=\ref[M]'>Hunter</A>
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Sentinel;mob=\ref[M]'>Sentinel</A>
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Queen;mob=\ref[M]'>Queen</A> \] |
\[ Crew: <A href='?src=\ref[src];simplemake=human;mob=\ref[M]'>Human</A>
<A href='?src=\ref[src];simplemake=human;species=Unathi;mob=\ref[M]'>Unathi</A>
<A href='?src=\ref[src];simplemake=human;species=Tajaran;mob=\ref[M]'>Tajaran</A>
<A href='?src=\ref[src];simplemake=human;species=Skrell;mob=\ref[M]'>Skrell</A>
<A href='?src=\ref[src];simplemake=human;species=Vox;mob=\ref[M]'>Vox</A> \] | \[
<A href='?src=\ref[src];simplemake=human;species=Skrell;mob=\ref[M]'>Skrell</A> \] | \[
<A href='?src=\ref[src];simplemake=nymph;mob=\ref[M]'>Nymph</A>
<A href='?src=\ref[src];simplemake=human;species='Diona';mob=\ref[M]'>Diona</A> \] |
\[ slime: <A href='?src=\ref[src];simplemake=slime;mob=\ref[M]'>Baby</A>,
@@ -1356,7 +1350,7 @@ proc/admin_notice(var/message, var/rights)
message_admins(msg)
else
usr << "You do not have access to this command."
/datum/admins/proc/add_tcrystals(mob/living/carbon/human/H as mob)
set category = "Debug"
set name = "Add Telecrystals"

View File

@@ -822,7 +822,7 @@ var/list/admin_verbs_mentor = list(
if(!istype(M, /mob/living/carbon/human))
usr << "\red You can only do this to humans!"
return
switch(alert("Are you sure you wish to edit this mob's appearance? Skrell, Unathi, Vox and Tajaran can result in unintended consequences.",,"Yes","No"))
switch(alert("Are you sure you wish to edit this mob's appearance? Skrell, Unathi, Tajaran can result in unintended consequences.",,"Yes","No"))
if("No")
return
var/new_facial = input("Please select facial hair color.", "Character Generation") as color

View File

@@ -1,7 +0,0 @@
/datum/admin_secret_item/random_event/trigger_xenomorph_infestation
name = "Trigger a Xenomorph Infestation"
/datum/admin_secret_item/random_event/trigger_xenomorph_infestation/execute(var/mob/user)
. = ..()
if(.)
return xenomorphs.attempt_random_spawn()

View File

@@ -1119,16 +1119,6 @@
log_admin("[key_name(usr)] AIized [key_name(H)]")
H.AIize()
else if(href_list["makealien"])
if(!check_rights(R_SPAWN)) return
var/mob/living/carbon/human/H = locate(href_list["makealien"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
return
usr.client.cmd_admin_alienize(H)
else if(href_list["makeslime"])
if(!check_rights(R_SPAWN)) return

View File

@@ -100,23 +100,6 @@
paiController.pai_candidates.Remove(candidate)
feedback_add_details("admin_verb","MPAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_alienize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make Alien"
if(!ticker)
alert("Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(src)] has alienized [M.key].")
spawn(10)
M:Alienize()
feedback_add_details("admin_verb","MKAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] made [key_name(M)] into an alien.")
message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into an alien.", 1)
else
alert("Invalid mob")
/client/proc/cmd_admin_slimeize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make slime"

View File

@@ -75,7 +75,6 @@
<option value='?_src_=vars;makeai=\ref[src]'>Make AI</option>
<option value='?_src_=vars;makerobot=\ref[src]'>Make cyborg</option>
<option value='?_src_=vars;makemonkey=\ref[src]'>Make monkey</option>
<option value='?_src_=vars;makealien=\ref[src]'>Make alien</option>
<option value='?_src_=vars;makeslime=\ref[src]'>Make slime</option>
"}

View File

@@ -90,10 +90,6 @@
if(V)
V.ex_act(2)
return
var/obj/machinery/bot/B = locate() in T
if(B)
B.ex_act(2)
return
var/obj/mecha/M = locate() in T
if(M)
M.visible_message("<span class='danger'>The blob attacks \the [M]!</span>")

View File

@@ -281,6 +281,9 @@
if(inactivity > duration) return inactivity
return 0
/client/proc/last_activity_seconds()
return inactivity / 10
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
/client/proc/send_resources()

View File

@@ -8,7 +8,7 @@
Sprites used when the clothing item is refit. This is done by setting icon_override.
For best results, if this is set then sprite_sheets should be null and vice versa, but that is by no means necessary.
Ideally, sprite_sheets_refit should be used for "hard" clothing items that can't change shape very well to fit the wearer (e.g. helmets, hardsuits),
while sprite_sheets should be used for "flexible" clothing items that do not need to be refitted (e.g. vox wearing jumpsuits).
while sprite_sheets should be used for "flexible" clothing items that do not need to be refitted (e.g. aliens wearing jumpsuits).
*/
var/list/sprite_sheets_refit = null
var/ear_protection = 0
@@ -204,9 +204,8 @@
body_parts_covered = HANDS
slot_flags = SLOT_GLOVES
attack_verb = list("challenged")
species_restricted = list("exclude","Unathi","Tajara", "Vox")
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/gloves.dmi',
"Teshari" = 'icons/mob/species/seromi/gloves.dmi',
)
@@ -264,7 +263,6 @@
var/on = 0
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Teshari" = 'icons/mob/species/seromi/head.dmi'
)
@@ -363,7 +361,6 @@
slot_flags = SLOT_MASK
body_parts_covered = FACE|EYES
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/masks.dmi',
"Teshari" = 'icons/mob/species/seromi/masks.dmi',
)
@@ -397,9 +394,8 @@
slowdown = SHOES_SLOWDOWN
force = 2
var/overshoes = 0
species_restricted = list("exclude","Teshari", "Unathi","Tajara","Vox")
species_restricted = list("exclude","Teshari", "Unathi","Tajara")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/shoes.dmi',
"Teshari" = 'icons/mob/species/seromi/shoes.dmi',
)
@@ -474,7 +470,6 @@
w_class = 3
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi',
"Teshari" = 'icons/mob/species/seromi/suit.dmi'
)
@@ -511,7 +506,6 @@
var/rolled_down = -1 //0 = unrolled, 1 = rolled, -1 = cannot be toggled
var/rolled_sleeves = -1 //0 = unrolled, 1 = rolled, -1 = cannot be toggled
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/uniform.dmi',
"Teshari" = 'icons/mob/species/seromi/uniform.dmi'
)

View File

@@ -27,7 +27,6 @@ BLIND // can't see anything
var/obj/screen/overlay = null
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi',
"Teshari" = 'icons/mob/species/seromi/eyes.dmi'
)

View File

@@ -10,7 +10,6 @@
desc = "an ultra rare hat. It commands a certain respect."
icon_state = "petehat"
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Teshari" = 'icons/mob/species/seromi/head.dmi'
)

View File

@@ -43,12 +43,6 @@
siemens_coefficient = 0.7
body_parts_covered = FACE|EYES
/obj/item/clothing/mask/gas/swat/vox
name = "\improper alien mask"
desc = "Clearly not designed for a human face."
body_parts_covered = 0 //Hack to allow vox to eat while wearing this mask.
species_restricted = list("Vox")
/obj/item/clothing/mask/gas/syndicate
name = "tactical mask"
desc = "A close-fitting tactical mask that can be connected to an air supply."

View File

@@ -28,141 +28,3 @@
/obj/item/clothing/suit/space/skrell/black
icon_state = "skrell_suit_black"
item_state = "skrell_suit_black"
// Vox space gear (vaccuum suit, low pressure armour)
// Can't be equipped by any other species due to bone structure and vox cybernetics.
/obj/item/clothing/suit/space/vox
w_class = 3
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank)
slowdown = 2
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.6
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("Vox")
/obj/item/clothing/head/helmet/space/vox
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.6
item_flags = STOPPRESSUREDAMAGE
species_restricted = list("Vox")
/obj/item/clothing/head/helmet/space/vox/pressure
name = "alien helmet"
icon_state = "vox-pressure"
item_state = "vox-pressure"
desc = "Hey, wasn't this a prop in \'The Abyss\'?"
/obj/item/clothing/suit/space/vox/pressure
name = "alien pressure suit"
icon_state = "vox-pressure"
item_state = "vox-pressure"
desc = "A huge, armoured, pressurized suit, designed for distinctly nonhuman proportions."
/obj/item/clothing/head/helmet/space/vox/carapace
name = "alien visor"
icon_state = "vox-carapace"
item_state = "vox-carapace"
desc = "A glowing visor, perhaps stolen from a depressed Cylon."
/obj/item/clothing/suit/space/vox/carapace
name = "alien carapace armour"
icon_state = "vox-carapace"
item_state = "vox-carapace"
desc = "An armoured, segmented carapace with glowing purple lights. It looks pretty run-down."
/obj/item/clothing/head/helmet/space/vox/stealth
name = "alien stealth helmet"
icon_state = "vox-stealth"
item_state = "vox-stealth"
desc = "A smoothly contoured, matte-black alien helmet."
/obj/item/clothing/suit/space/vox/stealth
name = "alien stealth suit"
icon_state = "vox-stealth"
item_state = "vox-stealth"
desc = "A sleek black suit. It seems to have a tail, and is very heavy."
/obj/item/clothing/head/helmet/space/vox/medic
name = "alien goggled helmet"
icon_state = "vox-medic"
item_state = "vox-medic"
desc = "An alien helmet with enormous goggled lenses."
/obj/item/clothing/suit/space/vox/medic
name = "alien armour"
icon_state = "vox-medic"
item_state = "vox-medic"
desc = "An almost organic looking nonhuman pressure suit."
/obj/item/clothing/under/vox
has_sensor = 0
species_restricted = list("Vox")
/obj/item/clothing/under/vox/vox_casual
name = "alien clothing"
desc = "This doesn't look very comfortable."
icon_state = "vox-casual-1"
item_state = "vox-casual-1"
body_parts_covered = LEGS
/obj/item/clothing/under/vox/vox_robes
name = "alien robes"
desc = "Weird and flowing!"
icon_state = "vox-casual-2"
item_state = "vox-casual-2"
/obj/item/clothing/gloves/yellow/vox
desc = "These bizarre gauntlets seem to be fitted for... bird claws?"
name = "insulated gauntlets"
icon_state = "gloves-vox"
item_state = "gloves-vox"
siemens_coefficient = 0
permeability_coefficient = 0.05
species_restricted = list("Vox")
/obj/item/clothing/shoes/magboots/vox
desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor."
name = "vox magclaws"
item_state = "boots-vox"
icon_state = "boots-vox"
species_restricted = list("Vox")
action_button_name = "Toggle the magclaws"
/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user)
if(src.magpulse)
item_flags &= ~NOSLIP
magpulse = 0
canremove = 1
user << "You relax your deathgrip on the flooring."
else
//make sure these can only be used when equipped.
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if (H.shoes != src)
user << "You will have to put on the [src] before you can do that."
return
item_flags |= NOSLIP
magpulse = 1
canremove = 0 //kinda hard to take off magclaws when you are gripping them tightly.
user << "You dig your claws deeply into the flooring, bracing yourself."
user << "It would be hard to take off the [src] without relaxing your grip first."
user.update_action_buttons()
//In case they somehow come off while enabled.
/obj/item/clothing/shoes/magboots/vox/dropped(mob/user as mob)
..()
if(src.magpulse)
user.visible_message("The [src] go limp as they are removed from [usr]'s feet.", "The [src] go limp as they are removed from your feet.")
item_flags &= ~NOSLIP
magpulse = 0
canremove = 1
/obj/item/clothing/shoes/magboots/vox/examine(mob/user)
..(user)
if (magpulse)
user << "It would be hard to take these off without relaxing your grip first." //theoretically this message should only be seen by the wearer when the claws are equipped.

View File

@@ -18,7 +18,7 @@
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona", "Xenomorph")
species_restricted = list("exclude","Diona")
var/obj/machinery/camera/camera
var/list/camera_networks
@@ -63,7 +63,7 @@
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona", "Xenomorph")
species_restricted = list("exclude","Diona")
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.

View File

@@ -21,12 +21,14 @@
var/cash_stored = 0
var/obj/item/confirm_item
var/datum/money_account/linked_account
var/account_to_connect = null
// Claim machine ID
/obj/machinery/cash_register/New()
machine_id = "[station_name()] RETAIL #[num_financial_terminals++]"
cash_stored = rand(10, 70)*10
transaction_devices += src // Global reference list to be properly set up by /proc/setup_economy()
/obj/machinery/cash_register/examine(mob/user as mob)
@@ -39,6 +41,9 @@
/obj/machinery/cash_register/attack_hand(mob/user as mob)
// Don't be accessible from the wrong side of the machine
if(get_dir(src, user) & reverse_dir[src.dir]) return
if(cash_open)
if(cash_stored)
spawn_money(cash_stored, loc, user)
@@ -278,26 +283,24 @@
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
return
// Access account for transaction
if(check_account())
if(transaction_amount > SC.worth)
src.visible_message("\icon[src]<span class='warning'>Not enough money.</span>")
else
// Insert cash into magical slot
SC.worth -= transaction_amount
SC.update_icon()
if(!SC.worth)
if(ishuman(SC.loc))
var/mob/living/carbon/human/H = SC.loc
H.drop_from_inventory(SC)
qdel(SC)
cash_stored += transaction_amount
if(transaction_amount > SC.worth)
src.visible_message("\icon[src]<span class='warning'>Not enough money.</span>")
else
// Insert cash into magical slot
SC.worth -= transaction_amount
SC.update_icon()
if(!SC.worth)
if(ishuman(SC.loc))
var/mob/living/carbon/human/H = SC.loc
H.drop_from_inventory(SC)
qdel(SC)
cash_stored += transaction_amount
// Save log
add_transaction_log("n/A", "Cash", transaction_amount)
// Save log
add_transaction_log("n/A", "Cash", transaction_amount)
// Confirm and reset
transaction_complete()
// Confirm and reset
transaction_complete()
/obj/machinery/cash_register/proc/scan_item_price(obj/O)
@@ -436,39 +439,33 @@
cash_locked = 0
open_cash_box()
//--Premades--//
/obj/machinery/cash_register/command
New()
linked_account = department_accounts["Command"]
..()
/obj/machinery/cash_register/medical
account_to_connect = "Command"
..()
New()
linked_account = department_accounts["Medical"]
..()
/obj/machinery/cash_register/medical
account_to_connect = "Medical"
..()
/obj/machinery/cash_register/engineering
New()
linked_account = department_accounts["Engineering"]
..()
account_to_connect = "Engineering"
..()
/obj/machinery/cash_register/science
New()
linked_account = department_accounts["Science"]
..()
account_to_connect = "Science"
..()
/obj/machinery/cash_register/security
New()
linked_account = department_accounts["Security"]
..()
account_to_connect = "Security"
..()
/obj/machinery/cash_register/cargo
New()
linked_account = department_accounts["Cargo"]
..()
account_to_connect = "Cargo"
..()
/obj/machinery/cash_register/civilian
New()
linked_account = department_accounts["Civilian"]
..()
account_to_connect = "Civilian"
..()

View File

@@ -52,8 +52,7 @@
/datum/species/skrell = 12,
/datum/species/teshari = 9, // Skrell sponsored!
/datum/species/tajaran = 7,
/datum/species/unathi = 7,
/datum/species/vox = 1
/datum/species/unathi = 7
)
//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
@@ -81,6 +80,7 @@ var/global/list/datum/money_account/department_accounts = list()
var/global/num_financial_terminals = 1
var/global/next_account_number = 0
var/global/list/all_money_accounts = list()
var/global/list/transaction_devices = list()
var/global/economy_init = 0
/proc/setup_economy()
@@ -102,6 +102,13 @@ var/global/economy_init = 0
create_department_account("Vendor")
vendor_account = department_accounts["Vendor"]
for(var/obj/item/device/retail_scanner/RS in transaction_devices)
if(RS.account_to_connect)
RS.linked_account = department_accounts[RS.account_to_connect]
for(var/obj/machinery/cash_register/CR in transaction_devices)
if(CR.account_to_connect)
CR.linked_account = department_accounts[CR.account_to_connect]
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [game_year]"
economy_init = 1

View File

@@ -17,6 +17,7 @@
var/obj/item/confirm_item
var/datum/money_account/linked_account
var/account_to_connect = null
// Claim machine ID
@@ -24,6 +25,7 @@
machine_id = "[station_name()] RETAIL #[num_financial_terminals++]"
if(locate(/obj/structure/table) in loc)
pixel_y = 3
transaction_devices += src // Global reference list to be properly set up by /proc/setup_economy()
// Always face the user when put on a table
@@ -315,36 +317,29 @@
//--Premades--//
/obj/item/device/retail_scanner/command
New()
linked_account = department_accounts["Command"]
..()
/obj/item/device/retail_scanner/medical
account_to_connect = "Command"
..()
New()
linked_account = department_accounts["Medical"]
..()
/obj/item/device/retail_scanner/medical
account_to_connect = "Medical"
..()
/obj/item/device/retail_scanner/engineering
New()
linked_account = department_accounts["Engineering"]
..()
account_to_connect = "Engineering"
..()
/obj/item/device/retail_scanner/science
New()
linked_account = department_accounts["Science"]
..()
account_to_connect = "Science"
..()
/obj/item/device/retail_scanner/security
New()
linked_account = department_accounts["Security"]
..()
account_to_connect = "Security"
..()
/obj/item/device/retail_scanner/cargo
New()
linked_account = department_accounts["Cargo"]
..()
account_to_connect = "Cargo"
..()
/obj/item/device/retail_scanner/civilian
New()
linked_account = department_accounts["Civilian"]
..()
account_to_connect = "Civilian"
..()

View File

@@ -86,12 +86,6 @@
"admin","ponies","heresy","meow","Pun Pun","monkey","Ian","moron","pizza","message","spam",\
"director", "Hello", "Hi!"," ","nuke","crate","dwarf","xeno")
/datum/event/ionstorm/tick()
if(botEmagChance)
for(var/obj/machinery/bot/bot in world)
if(prob(botEmagChance))
bot.emag_act(1)
/datum/event/ionstorm/end()
spawn(rand(5000,8000))
if(prob(50))

View File

@@ -1151,23 +1151,3 @@
set_trait(TRAIT_PRODUCTION,7)
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,3)
// Alien weeds.
/datum/seed/xenomorph
name = "xenomorph"
seed_name = "alien weed"
display_name = "alien weeds"
force_layer = 3
chems = list("phoron" = list(1,3))
/datum/seed/xenomorph/New()
..()
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_IMMUTABLE,1)
set_trait(TRAIT_PRODUCT_COLOUR,"#3D1934")
set_trait(TRAIT_FLESH_COLOUR,"#3D1934")
set_trait(TRAIT_PLANT_COLOUR,"#3D1934")
set_trait(TRAIT_PRODUCTION,1)
set_trait(TRAIT_YIELD,-1)
set_trait(TRAIT_SPREAD,2)
set_trait(TRAIT_POTENCY,50)

View File

@@ -556,8 +556,8 @@ var/list/name_to_material
sheet_plural_name = "ingots"
// Adminspawn only, do not let anyone get this.
/material/voxalloy
name = "voxalloy"
/material/alienalloy
name = "alienalloy"
display_name = "durable alloy"
stack_type = null
icon_colour = "#6C7364"
@@ -640,21 +640,6 @@ var/list/name_to_material
/material/cult/reinf/place_dismantled_product(var/turf/target)
new /obj/effect/decal/remains/human(target)
/material/resin
name = "resin"
icon_colour = "#E85DD8"
dooropen_noise = 'sound/effects/attackblob.ogg'
door_icon_base = "resin"
melting_point = T0C+300
sheet_singular_name = "blob"
sheet_plural_name = "blobs"
/material/resin/can_open_material_door(var/mob/living/user)
var/mob/living/carbon/M = user
if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
return 1
return 0
//TODO PLACEHOLDERS:
/material/leather
name = "leather"

View File

@@ -21,7 +21,7 @@
generate_loot()
/obj/structure/closet/crate/secure/loot/proc/generate_loot()
var/loot = rand(1, 100)
var/loot = rand(1, 99)
switch(loot)
if(1 to 5) // Common things go, 5%
new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src)
@@ -104,7 +104,7 @@
if(88)
new/obj/item/xenos_claw(src)
if(89)
new/obj/item/organ/internal/xenos/plasmavessel(src)
new/obj/item/clothing/head/bearpelt(src)
if(90)
new/obj/item/organ/internal/heart(src)
if(91)
@@ -142,8 +142,6 @@
if(99)
new/obj/item/weapon/storage/belt/champion(src)
new/obj/item/clothing/mask/luchador(src)
if(100)
new/obj/item/clothing/head/bearpelt(src)
/obj/structure/closet/crate/secure/loot/togglelock(mob/user as mob)
if(!locked)

View File

@@ -9,7 +9,6 @@ var/list/holder_mob_icon_cache = list()
show_messages = 1
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Teshari" = 'icons/mob/species/seromi/head.dmi'
)

View File

@@ -1,34 +1,3 @@
/datum/language/xenocommon
name = "Xenomorph"
colour = "alien"
desc = "The common tongue of the xenomorphs."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
key = "4"
flags = RESTRICTED
syllables = list("sss","sSs","SSS")
/datum/language/xenos
name = "Hivemind"
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
/datum/language/xenos/check_special_condition(var/mob/other)
var/mob/living/carbon/M = other
if(!istype(M))
return 1
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
return 1
return 0
/datum/language/ling
name = "Changeling"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
@@ -68,21 +37,6 @@
speaker_mask = B.truename
..(speaker,message,speaker_mask)
/datum/language/vox
name = "Vox-pidgin"
desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else."
speech_verb = "shrieks"
ask_verb = "creels"
exclaim_verb = "SHRIEKS"
colour = "vox"
key = "5"
flags = WHITELISTED
syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \
"SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA")
/datum/language/vox/get_random_name()
return ..(FEMALE,1,6)
/datum/language/cultcommon
name = "Cult"
desc = "The chants of the occult, the incomprehensible."

View File

@@ -29,6 +29,8 @@
access_scanner.req_access = req_access.Copy()
access_scanner.req_one_access = req_one_access.Copy()
turn_on()
/mob/living/bot/Life()
..()
if(health <= 0)
@@ -125,3 +127,70 @@
/mob/living/bot/attack_throat()
return
/******************************************************************/
// Navigation procs
// Used for A-star pathfinding
// Returns the surrounding cardinal turfs with open links
// Including through doors openable with the ID
/turf/proc/CardinalTurfsWithAccess(var/obj/item/weapon/card/id/ID)
var/L[] = new()
// for(var/turf/simulated/t in oview(src,1))
for(var/d in cardinal)
var/turf/simulated/T = get_step(src, d)
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
// Returns true if a link between A and B is blocked
// Movement through doors allowed if ID has access
/proc/LinkBlockedWithAccess(turf/A, turf/B, obj/item/weapon/card/id/ID)
if(A == null || B == null) return 1
var/adir = get_dir(A,B)
var/rdir = get_dir(B,A)
if((adir & (NORTH|SOUTH)) && (adir & (EAST|WEST))) // diagonal
var/iStep = get_step(A,adir&(NORTH|SOUTH))
if(!LinkBlockedWithAccess(A,iStep, ID) && !LinkBlockedWithAccess(iStep,B,ID))
return 0
var/pStep = get_step(A,adir&(EAST|WEST))
if(!LinkBlockedWithAccess(A,pStep,ID) && !LinkBlockedWithAccess(pStep,B,ID))
return 0
return 1
if(DirBlockedWithAccess(A,adir, ID))
return 1
if(DirBlockedWithAccess(B,rdir, ID))
return 1
for(var/obj/O in B)
if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER))
return 1
return 0
// Returns true if direction is blocked from loc
// Checks doors against access with given ID
/proc/DirBlockedWithAccess(turf/loc,var/dir,var/obj/item/weapon/card/id/ID)
for(var/obj/structure/window/D in loc)
if(!D.density) continue
if(D.dir == SOUTHWEST) return 1
if(D.dir == dir) return 1
for(var/obj/machinery/door/D in loc)
if(!D.density) continue
if(istype(D, /obj/machinery/door/window))
if( dir & D.dir ) return !D.check_access(ID)
//if((dir & SOUTH) && (D.dir & (EAST|WEST))) return !D.check_access(ID)
//if((dir & EAST ) && (D.dir & (NORTH|SOUTH))) return !D.check_access(ID)
else return !D.check_access(ID) // it's a real, air blocking door
return 0

View File

@@ -0,0 +1,438 @@
#define MULE_IDLE 0
#define MULE_MOVING 1
#define MULE_UNLOAD 2
#define MULE_LOST 3
#define MULE_CALC_MIN 4
#define MULE_CALC_MAX 10
#define MULE_PATH_DONE 11
// IF YOU CHANGE THOSE, UPDATE THEM IN pda.tmpl TOO
/mob/living/bot/mulebot
name = "Mulebot"
desc = "A Multiple Utility Load Effector bot."
icon_state = "mulebot0"
anchored = 1
density = 1
health = 150
maxHealth = 150
mob_bump_flag = HEAVY
botcard_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
var/busy = 0
var/mode = MULE_IDLE
var/atom/movable/load
var/crates_only = 1
var/auto_return = 1
var/safety = 1
var/list/path = list()
var/frustration = 0
var/turf/target
var/targetName
var/turf/home
var/homeName
var/turf/obstacle
var/global/amount = 0
/mob/living/bot/mulebot/New()
..()
var/turf/T = get_turf(loc)
var/obj/machinery/navbeacon/N = locate() in T
if(N)
home = T
homeName = N.location
else
homeName = "Unset"
suffix = num2text(++amount) // Starts from 1
name = "Mulebot #[suffix]"
/mob/living/bot/mulebot/MouseDrop_T(var/atom/movable/C, var/mob/user)
if(user.stat)
return
if(!istype(C) || C.anchored || get_dist(user, src) > 1 || get_dist(src, C) > 1 )
return
load(C)
/mob/living/bot/mulebot/attack_hand(var/mob/user)
interact(user)
/mob/living/bot/mulebot/proc/interact(var/mob/user)
var/dat
dat += "<TT><B>Multiple Utility Load Effector Mk. III</B></TT><BR><BR>"
dat += "ID: [suffix]<BR>"
dat += "Power: [on ? "On" : "Off"]<BR>"
if(!open)
dat += "Status: "
switch(mode)
if(MULE_IDLE)
dat += "Ready"
if(MULE_MOVING, MULE_UNLOAD, MULE_PATH_DONE)
dat += "Navigating"
if(MULE_UNLOAD)
dat += "Unloading"
if(MULE_LOST)
dat += "Processing commands"
if(MULE_CALC_MIN to MULE_CALC_MAX)
dat += "Calculating navigation path"
dat += "<BR>Current Load: [load ? load.name : "<i>none</i>"]<BR>"
if(locked)
dat += "<HR>Controls are locked"
else
dat += "<HR>Controls are unlocked<BR><BR>"
if(!locked || issilicon(user))
dat += "<A href='byond://?src=\ref[src];op=power'>Toggle power</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=stop'>Stop</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=go'>Proceed</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=home'>Return to home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=destination'>Set destination</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=sethome'>Set home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=autoret'>Toggle auto return home</A> ([auto_return ? "On" : "Off"])<BR>"
dat += "<A href='byond://?src=\ref[src];op=cargotypes'>Toggle non-standard cargo</A> ([crates_only ? "Off" : "On"])<BR>"
if(load)
dat += "<A href='byond://?src=\ref[src];op=unload'>Unload now</A><BR>"
dat += "<HR>The maintenance hatch is closed.<BR>"
else
if(!issilicon(user))
dat += "The maintenance hatch is open.<BR><BR>"
dat += "<A href='byond://?src=\ref[src];op=safety'>Toggle safety</A> ([safety ? "On" : "Off - DANGER"])<BR>"
else
dat += "The bot is in maintenance mode and cannot be controlled.<BR>"
user << browse("<HEAD><TITLE>Mulebot [suffix ? "([suffix])" : ""]</TITLE></HEAD>[dat]", "window=mulebot;size=350x500")
onclose(user, "mulebot")
return
/mob/living/bot/mulebot/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
add_fingerprint(usr)
switch(href_list["op"])
if("power")
if(on)
turn_off()
else
turn_on()
visible_message("[usr] switches [on ? "on" : "off"] [src].")
if("stop")
obeyCommand("Stop")
if("go")
obeyCommand("GoTD")
if("home")
obeyCommand("Home")
if("destination")
obeyCommand("SetD")
if("sethome")
var/new_dest
var/list/beaconlist = new()
for(var/obj/machinery/navbeacon/N in navbeacons)
beaconlist.Add(N.location)
beaconlist[N.location] = N
if(beaconlist.len)
new_dest = input("Select new home tag", "Mulebot [suffix ? "([suffix])" : ""]", null) in null|beaconlist
else
alert("No destination beacons available.")
if(new_dest)
home = get_turf(beaconlist[new_dest])
homeName = new_dest
if("unload")
unload()
if("autoret")
auto_return = !auto_return
if("cargotypes")
crates_only = !crates_only
if("safety")
safety = !safety
interact(usr)
/mob/living/bot/mulebot/attackby(var/obj/item/O, var/mob/user)
..()
update_icons()
/mob/living/bot/mulebot/proc/obeyCommand(var/command)
switch(command)
if("Home")
mode = MULE_IDLE
target = home
targetName = "Home"
mode = MULE_LOST
if("SetD")
var/new_dest
var/list/beaconlist = new()
for(var/obj/machinery/navbeacon/N in navbeacons)
beaconlist.Add(N.location)
beaconlist[N.location] = N
if(beaconlist.len)
new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]") in null|beaconlist
else
alert("No destination beacons available.")
if(new_dest)
target = get_turf(beaconlist[new_dest])
targetName = new_dest
if("GoTD")
if(mode == MULE_IDLE)
mode = MULE_LOST
if("Stop")
mode = MULE_IDLE
/mob/living/bot/mulebot/emag_act(var/remaining_charges, var/user)
locked = !locked
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
flick("mulebot-emagged", src)
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
return 1
/mob/living/bot/mulebot/update_icons()
if(open)
icon_state = "mulebot-hatch"
return
if(mode == MULE_MOVING || mode == MULE_UNLOAD)
icon_state = "mulebot1"
return
icon_state = "mulebot0"
/mob/living/bot/mulebot/Life()
..()
if(busy)
return
if(!safety && prob(1))
flick("mulebot-emagged", src)
switch(mode)
if(MULE_IDLE) // Idle
return
if(MULE_MOVING) // Moving to target
if(!target) // Return home
if(auto_return && home)
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
return
if(loc == target) // Unload or stop
custom_emote(2, "makes a chiming sound.")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
mode = MULE_UNLOAD
update_icons()
return
if(path.len) // Move
makeStep()
sleep(10)
if(path.len)
makeStep()
else
mode = MULE_LOST
update_icons()
return
if(MULE_UNLOAD)
unload(dir)
if(auto_return && home && (loc != home))
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
return
if(MULE_LOST) // Lost my way
if(target)
spawn(0)
calc_path(obstacle)
mode = MULE_CALC_MIN
else
mode = MULE_IDLE
update_icons()
return
if(MULE_CALC_MIN to MULE_CALC_MAX) // Calcing path
if(path.len)
mode = MULE_PATH_DONE
update_icons()
else
++mode
return
if(MULE_PATH_DONE) // Done with path
obstacle = null
if(path.len)
frustration = 0
mode = MULE_MOVING
else
if(home)
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
/mob/living/bot/mulebot/Bump(var/mob/living/M)
if(!safety && istype(M))
visible_message("<span class='warning'>[src] knocks over [M]!</span>")
M.Stun(8)
M.Weaken(5)
..()
/mob/living/bot/mulebot/proc/makeStep()
var/turf/next = path[1]
if(next == loc)
path -= next
return
var/moved = step_towards(src, next)
if(moved)
frustration = 0
path -= next
else if(frustration < 6)
if(frustration == 3)
custom_emote(2, "makes an annoyed buzzing sound")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
++frustration
else
custom_emote(2, "makes a sighing buzz.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
obstacle = next
mode = MULE_LOST
/mob/living/bot/mulebot/proc/runOver(var/mob/living/carbon/human/H)
if(istype(H)) // No safety checks - WILL run over lying humans. Stop ERPing in the maint!
visible_message("<span class='warning'>[src] drives over [H]!</span>")
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
var/damage = rand(5, 7)
H.apply_damage(2 * damage, BRUTE, BP_HEAD)
H.apply_damage(2 * damage, BRUTE, BP_TORSO)
H.apply_damage(0.5 * damage, BRUTE, BP_L_LEG)
H.apply_damage(0.5 * damage, BRUTE, BP_R_LEG)
H.apply_damage(0.5 * damage, BRUTE, BP_L_ARM)
H.apply_damage(0.5 * damage, BRUTE, BP_R_ARM)
blood_splatter(src, H, 1)
..()
/mob/living/bot/mulebot/relaymove(var/mob/user, var/direction)
if(load == user)
unload(direction)
/mob/living/bot/mulebot/explode()
unload(pick(0, 1, 2, 4, 8))
visible_message("<span class='danger'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
new /obj/item/device/assembly/prox_sensor(Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
new /obj/item/stack/cable_coil/cut(Tsec)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
new /obj/effect/decal/cleanable/blood/oil(Tsec)
..()
/mob/living/bot/mulebot/proc/calc_path(var/turf/avoid = null)
path = AStar(loc, target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id = botcard, exclude = avoid)
if(!path)
path = list()
/mob/living/bot/mulebot/proc/load(var/atom/movable/C)
if(busy || load || get_dist(C, src) > 1 || !isturf(C.loc))
return
for(var/obj/structure/plasticflaps/P in src.loc)//Takes flaps into account
if(!CanPass(C,P))
return
if(crates_only && !istype(C,/obj/structure/closet/crate))
custom_emote(2, "makes a sighing buzz.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
return
var/obj/structure/closet/crate/crate = C
if(istype(crate))
crate.close()
//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
//if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
// return
busy = 1
C.loc = loc
sleep(2)
if(C.loc != loc) //To prevent you from going onto more than one bot.
return
C.loc = src
load = C
C.pixel_y += 9
if(C.layer < layer)
C.layer = layer + 0.1
overlays += C
busy = 0
/mob/living/bot/mulebot/proc/unload(var/dirn = 0)
if(!load || busy)
return
busy = 1
overlays.Cut()
load.loc = loc
load.pixel_y -= 9
load.layer = initial(load.layer)
if(dirn)
step(load, dirn)
load = null
for(var/atom/movable/AM in src)
if(AM == botcard || AM == access_scanner)
continue
AM.loc = loc
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
busy = 0
#undef MULE_IDLE
#undef MULE_MOVING
#undef MULE_UNLOAD
#undef MULE_LOST
#undef MULE_CALC_MIN
#undef MULE_CALC_MAX
#undef MULE_PATH_DONE

View File

@@ -1,14 +0,0 @@
/mob/living/carbon/alien/larva
name = "alien larva"
real_name = "alien larva"
adult_form = /mob/living/carbon/human
speak_emote = list("hisses")
icon_state = "larva"
language = "Hivemind"
maxHealth = 25
health = 25
/mob/living/carbon/alien/larva/New()
..()
add_language("Xenomorph") //Bonus language.
internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src)

View File

@@ -1,12 +0,0 @@
//Larvae regenerate health and nutrition from plasma and alien weeds.
/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment)
if(!environment) return
var/turf/T = get_turf(src)
if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents))
update_progression()
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)

View File

@@ -1,12 +0,0 @@
/mob/living/carbon/alien/larva/confirm_evolution()
src << "\blue <b>You are growing into a beautiful alien! It is time to choose a caste.</b>"
src << "\blue There are three to choose from:"
src << "<B>Hunters</B> \blue are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves."
src << "<B>Sentinels</B> \blue are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters."
src << "<B>Drones</B> \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
return alien_caste ? "Xenomorph [alien_caste]" : null
/mob/living/carbon/alien/larva/show_evolution_blurb()
return

View File

@@ -71,10 +71,6 @@
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA]
if(P)
stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
if(back && istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/suit = back
var/cell_status = "ERROR"
@@ -235,9 +231,9 @@
// called when something steps onto a human
// this handles mulebots and vehicles
/mob/living/carbon/human/Crossed(var/atom/movable/AM)
if(istype(AM, /obj/machinery/bot/mulebot))
var/obj/machinery/bot/mulebot/MB = AM
MB.RunOver(src)
if(istype(AM, /mob/living/bot/mulebot))
var/mob/living/bot/mulebot/MB = AM
MB.runOver(src)
if(istype(AM, /obj/vehicle))
var/obj/vehicle/V = AM

View File

@@ -49,116 +49,6 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] [failed ? "tried to tackle" : "has tackled"] down []!</B>", src, T), 1)
/mob/living/carbon/human/proc/leap()
set category = "Abilities"
set name = "Leap"
set desc = "Leap at a target and grab them aggressively."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
var/list/choices = list()
for(var/mob/living/M in view(6,src))
if(!istype(M,/mob/living/silicon))
choices += M
choices -= src
var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices
if(!T || !src || src.stat) return
if(get_dist(get_turf(T), get_turf(src)) > 4) return
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
last_special = world.time + 75
status_flags |= LEAPING
src.visible_message("<span class='danger'>\The [src] leaps at [T]!</span>")
src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1)
sleep(5)
if(status_flags & LEAPING) status_flags &= ~LEAPING
if(!src.Adjacent(T))
src << "<span class='warning'>You miss!</span>"
return
T.Weaken(3)
// Pariahs are not good at leaping. This is snowflakey, pls fix.
if(species.name == "Vox Pariah")
src.Weaken(5)
return
var/use_hand = "left"
if(l_hand)
if(r_hand)
src << "<span class='danger'>You need to have one hand free to grab someone.</span>"
return
else
use_hand = "right"
src.visible_message("<span class='warning'><b>\The [src]</b> seizes [T] aggressively!</span>")
var/obj/item/weapon/grab/G = new(src,T)
if(use_hand == "left")
l_hand = G
else
r_hand = G
G.state = GRAB_PASSIVE
G.icon_state = "grabbed1"
G.synch()
/mob/living/carbon/human/proc/gut()
set category = "Abilities"
set name = "Gut"
set desc = "While grabbing someone aggressively, rip their guts out or tear them apart."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying)
src << "\red You cannot do that in your current state."
return
var/obj/item/weapon/grab/G = locate() in src
if(!G || !istype(G))
src << "\red You are not grabbing anyone."
return
if(G.state < GRAB_AGGRESSIVE)
src << "\red You must have an aggressive grab to gut your prey!"
return
last_special = world.time + 50
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s body with its claws!</span>")
if(istype(G.affecting,/mob/living/carbon/human))
var/mob/living/carbon/human/H = G.affecting
H.apply_damage(50,BRUTE)
if(H.stat == 2)
H.gib()
else
var/mob/living/M = G.affecting
if(!istype(M)) return //wut
M.apply_damage(50,BRUTE)
if(M.stat == 2)
M.gib()
/mob/living/carbon/human/proc/commune()
set category = "Abilities"
set name = "Commune with creature"

View File

@@ -14,10 +14,6 @@
h_style = "Unathi Horns"
..(new_loc, "Unathi")
/mob/living/carbon/human/vox/New(var/new_loc)
h_style = "Short Vox Quills"
..(new_loc, "Vox")
/mob/living/carbon/human/diona/New(var/new_loc)
..(new_loc, "Diona")

View File

@@ -1,142 +0,0 @@
/datum/species/vox
name = "Vox"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = "Vox-pidgin"
language = "Galactic Common"
num_alternate_languages = 1
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \
alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \
refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \
smell.<br/><br/>Most humans will never meet a Vox raider, instead learning of this insular species through \
dealing with their traders and merchants; those that do rarely enjoy the experience."
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
gluttonous = 2
breath_type = "nitrogen"
poison_type = "oxygen"
siemens_coefficient = 0.2
flags = NO_SCAN | NO_MINOR_CUT
spawn_flags = CAN_JOIN | IS_WHITELISTED
appearance_flags = HAS_EYE_COLOR
blood_color = "#2299FC"
flesh_color = "#808D11"
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap
)
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head/vox),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
O_EYES = /obj/item/organ/internal/eyes,
"stack" = /obj/item/organ/internal/stack/vox
)
/datum/species/vox/get_random_name(var/gender)
var/datum/language/species_language = all_languages[default_language]
return species_language.get_random_name(gender)
/datum/species/vox/equip_survival_gear(var/mob/living/carbon/human/H)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H), slot_r_hand)
H.internal = H.back
else
H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_r_hand)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
H.internal = H.r_hand
H.internals.icon_state = "internal1"
/datum/species/vox/get_station_variant()
return "Vox Pariah"
// Joining as a station vox will give you this template, hence IS_RESTRICTED flag.
/datum/species/vox/pariah
name = "Vox Pariah"
rarity_value = 0.1
speech_chance = 60 // No volume control.
siemens_coefficient = 0.5 // Ragged scaleless patches.
warning_low_pressure = (WARNING_LOW_PRESSURE-20)
hazard_low_pressure = (HAZARD_LOW_PRESSURE-10)
total_health = 80
cold_level_1 = 130
cold_level_2 = 100
cold_level_3 = 60
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite)
// Pariahs have no stack.
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/pariah_brain,
O_EYES = /obj/item/organ/internal/eyes
)
flags = IS_RESTRICTED | NO_SCAN | HAS_EYE_COLOR
// No combat skills for you.
/datum/species/vox/pariah/can_shred(var/mob/living/carbon/human/H, var/ignore_intent)
return 0
// Pariahs are really gross.
/datum/species/vox/pariah/handle_environment_special(var/mob/living/carbon/human/H)
if(prob(5))
var/stink_range = rand(3,5)
for(var/mob/living/M in range(H,stink_range))
if(M.stat || M == H)
continue
var/mob/living/carbon/human/target = M
if(istype(target))
if(target.internals)
continue
if(target.head && (target.head.body_parts_covered & FACE) && (target.head.flags & AIRTIGHT))
continue
if(target.wear_mask && (target.wear_mask.body_parts_covered & FACE) && (target.wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
continue
M << "<span class='danger'>A terrible stench emanates from \the [H].</span>"
/datum/species/vox/pariah/get_bodytype()
return "Vox"

View File

@@ -1,159 +0,0 @@
// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
/obj/item/alien_embryo
name = "alien embryo"
desc = "All slimy and yuck."
icon = 'icons/mob/alien.dmi'
icon_state = "larva0_dead"
var/mob/living/affected_mob
var/stage = 0
/obj/item/alien_embryo/New()
if(istype(loc, /mob/living))
affected_mob = loc
processing_objects.Add(src)
spawn(0)
AddInfectionImages(affected_mob)
else
qdel(src)
/obj/item/alien_embryo/Destroy()
if(affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
spawn(0)
RemoveInfectionImages(affected_mob)
..()
/obj/item/alien_embryo/process()
if(!affected_mob) return
if(loc != affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
processing_objects.Remove(src)
spawn(0)
RemoveInfectionImages(affected_mob)
affected_mob = null
return
if(stage < 5 && prob(3))
stage++
spawn(0)
RefreshInfectionImage(affected_mob)
switch(stage)
if(2, 3)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
affected_mob << "\red Your throat feels sore."
if(prob(1))
affected_mob << "\red Mucous runs down the back of your throat."
if(4)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(2))
affected_mob << "\red Your muscles ache."
if(prob(20))
affected_mob.take_organ_damage(1)
if(prob(2))
affected_mob << "\red Your stomach hurts."
if(prob(20))
affected_mob.adjustToxLoss(1)
affected_mob.updatehealth()
if(5)
affected_mob << "\red You feel something tearing its way out of your stomach..."
affected_mob.adjustToxLoss(10)
affected_mob.updatehealth()
if(prob(50))
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
var/list/candidates = get_alien_candidates()
var/picked = null
// To stop clientless larva, we will check that our host has a client
// if we find no ghosts to become the alien. If the host has a client
// he will become the alien but if he doesn't then we will set the stage
// to 2, so we don't do a process heavy check everytime.
if(candidates.len)
picked = pick(candidates)
else if(affected_mob.client)
picked = affected_mob.key
else
stage = 4 // Let's try again later.
return
if(affected_mob.lying)
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
else
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
spawn(6)
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
new_xeno.key = picked
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
qdel(src)
/*----------------------------------------
Proc: RefreshInfectionImage()
Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
----------------------------------------*/
/obj/item/alien_embryo/proc/RefreshInfectionImage()
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)
for(var/mob/living/L in mob_list)
if(iscorgi(L) || iscarbon(L))
if(L.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: AddInfectionImages(C)
Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
----------------------------------------*/
/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
if(C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
----------------------------------------*/
/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
for(var/image/I in alien.client.images)
if(I.loc == C)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)

View File

@@ -1,231 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//TODO: Make these simple_animals
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
var/const/MAX_IMPREGNATION_TIME = 150
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger
name = "alien"
desc = "It has some sort of a tube at the end of its tail."
icon = 'icons/mob/alien.dmi'
icon_state = "facehugger"
item_state = "facehugger"
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = PROXMOVE
body_parts_covered = FACE|EYES
throw_range = 5
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/strength = 5
var/attached = 0
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
if(Attach(user))
return
..()
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
..()
user.drop_from_inventory(src)
Attach(M)
/obj/item/clothing/mask/facehugger/New()
if(config.aliens_allowed)
..()
else
qdel(src)
/obj/item/clothing/mask/facehugger/examine(mob/user)
..(user)
switch(stat)
if(DEAD,UNCONSCIOUS)
user << "\red \b [src] is not moving."
if(CONSCIOUS)
user << "\red \b [src] seems to be active."
if (sterile)
user << "\red \b It looks like the proboscis has been removed."
return
/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
if(I.force)
user.do_attack_animation(src)
Die()
return
/obj/item/clothing/mask/facehugger/bullet_act()
Die()
return
/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C+80)
Die()
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
..()
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
HasProximity(target)
return
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
if(stat == CONSCIOUS)
HasProximity(finder)
return 1
return
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
if(CanHug(AM))
Attach(AM)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
spawn(15)
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"
throwing = 0
GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if((!iscorgi(M) && !iscarbon(M)))
return
if(attached)
return
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
return
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
var/mob/living/L = M //just so I don't need to use :
if(loc == L) return
if(stat != CONSCIOUS) return
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
L.visible_message("\red \b [src] leaps at [L]'s face!")
if(iscarbon(M))
var/mob/living/carbon/target = L
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
target.equip_to_slot(src, slot_wear_mask)
target.contents += src // Monkey sanity check - Snapshot
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
var/mob/living/simple_animal/corgi/corgi = M
src.loc = corgi
corgi.facehugger = src
corgi.wear_mask = src
//C.regenerate_icons()
GoIdle() //so it doesn't jump the people that tear it off
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(L)
return
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
return
if(!sterile)
new /obj/item/alien_embryo(target)
target.status_flags |= XENO_HOST
target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
Die()
icon_state = "[initial(icon_state)]_impregnated"
if(iscorgi(target))
var/mob/living/simple_animal/corgi/C = target
src.loc = get_turf(C)
C.facehugger = null
else
target.visible_message("\red \b [src] violates [target]'s face!")
return
/obj/item/clothing/mask/facehugger/proc/GoActive()
if(stat == DEAD || stat == CONSCIOUS)
return
stat = CONSCIOUS
icon_state = "[initial(icon_state)]"
return
/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
if(stat == DEAD || stat == UNCONSCIOUS)
return
/* RemoveActiveIndicators() */
stat = UNCONSCIOUS
icon_state = "[initial(icon_state)]_inactive"
spawn(rand(min_time,max_time))
GoActive()
return
/obj/item/clothing/mask/facehugger/proc/Die()
if(stat == DEAD)
return
/* RemoveActiveIndicators() */
icon_state = "[initial(icon_state)]_dead"
stat = DEAD
src.visible_message("\red \b[src] curls up into a ball!")
return
/proc/CanHug(var/mob/M)
if(iscorgi(M))
return 1
if(!iscarbon(M))
return 0
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
return 0
return 1

View File

@@ -1,222 +0,0 @@
/proc/alien_queen_exists(var/ignore_self,var/mob/living/carbon/human/self)
for(var/mob/living/carbon/human/Q in living_mob_list)
if(self && ignore_self && self == Q)
continue
if(Q.species.name != "Xenomorph Queen")
continue
if(!Q.key || !Q.client || Q.stat)
continue
return 1
return 0
/mob/living/carbon/human/proc/gain_plasma(var/amount)
var/obj/item/organ/internal/xenos/plasmavessel/I = internal_organs_by_name[O_PLASMA]
if(!istype(I)) return
if(amount)
I.stored_plasma += amount
I.stored_plasma = max(0,min(I.stored_plasma,I.max_plasma))
/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ)
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA]
if(!istype(P))
src << "<span class='danger'>Your plasma vessel has been removed!</span>"
return
if(needs_organ)
var/obj/item/organ/internal/I = internal_organs_by_name[needs_organ]
if(!I)
src << "<span class='danger'>Your [needs_organ] has been removed!</span>"
return
else if((I.status & ORGAN_CUT_AWAY) || I.is_broken())
src << "<span class='danger'>Your [needs_organ] is too damaged to function!</span>"
return
if(P.stored_plasma < cost)
src << "\red You don't have enough phoron stored to do that."
return 0
if(needs_foundation)
var/turf/T = get_turf(src)
var/has_foundation
if(T)
//TODO: Work out the actual conditions this needs.
if(!(istype(T,/turf/space)))
has_foundation = 1
if(!has_foundation)
src << "\red You need a solid foundation to do that on."
return 0
P.stored_plasma -= cost
return 1
// Free abilities.
/mob/living/carbon/human/proc/transfer_plasma(mob/living/carbon/human/M as mob in oview())
set name = "Transfer Plasma"
set desc = "Transfer Plasma to another alien"
set category = "Abilities"
if (get_dist(src,M) <= 1)
src << "<span class='alium'>You need to be closer.</span>"
return
var/obj/item/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name[O_PLASMA]
if(!istype(I))
src << "<span class='alium'>Their plasma vessel is missing.</span>"
return
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
if (amount)
amount = abs(round(amount))
if(check_alien_ability(amount,0,O_PLASMA))
M.gain_plasma(amount)
M << "<span class='alium'>[src] has transfered [amount] plasma to you.</span>"
src << "<span class='alium'>You have transferred [amount] plasma to [M].</span>"
return
// Queen verbs.
/mob/living/carbon/human/proc/lay_egg()
set name = "Lay Egg (75)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
set category = "Abilities"
if(!config.aliens_allowed)
src << "You begin to lay an egg, but hesitate. You suspect it isn't allowed."
verbs -= /mob/living/carbon/human/proc/lay_egg
return
if(locate(/obj/effect/alien/egg) in get_turf(src))
src << "There's already an egg here."
return
if(check_alien_ability(75,1,O_EGG))
visible_message("<span class='alium'><B>[src] has laid an egg!</B></span>")
new /obj/effect/alien/egg(loc)
return
// Drone verbs.
/mob/living/carbon/human/proc/evolve()
set name = "Evolve (500)"
set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
set category = "Abilities"
if(alien_queen_exists())
src << "<span class='notice'>We already have an active queen.</span>"
return
if(check_alien_ability(500))
visible_message("<span class='alium'><B>[src] begins to twist and contort!</B></span>", "<span class='alium'>You begin to evolve!</span>")
src.set_species("Xenomorph Queen")
return
/mob/living/carbon/human/proc/plant()
set name = "Plant Weeds (50)"
set desc = "Plants some alien weeds"
set category = "Abilities"
if(check_alien_ability(50,1,O_RESIN))
visible_message("<span class='alium'><B>[src] has planted some alien weeds!</B></span>")
new /obj/effect/alien/weeds/node(loc)
return
/mob/living/carbon/human/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
set name = "Corrosive Acid (200)"
set desc = "Drench an object in acid, destroying it over time."
set category = "Abilities"
if(!O in oview(1))
src << "<span class='alium'>[O] is too far away.</span>"
return
// OBJ CHECK
var/cannot_melt
if(isobj(O))
var/obj/I = O
if(I.unacidable)
cannot_melt = 1
else
if(istype(O, /turf/simulated/wall))
var/turf/simulated/wall/W = O
if(W.material.flags & MATERIAL_UNMELTABLE)
cannot_melt = 1
else if(istype(O, /turf/simulated/floor))
var/turf/simulated/floor/F = O
if(F.flooring && (F.flooring.flags & TURF_ACID_IMMUNE))
cannot_melt = 1
if(cannot_melt)
src << "<span class='alium'>You cannot dissolve this object.</span>"
return
if(check_alien_ability(200,0,O_ACID))
new /obj/effect/alien/acid(get_turf(O), O)
visible_message("<span class='alium'><B>[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!</B></span>")
return
/mob/living/carbon/human/proc/neurotoxin(mob/target as mob in oview())
set name = "Spit Neurotoxin (50)"
set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear."
set category = "Abilities"
if(!check_alien_ability(50,0,O_ACID))
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot spit neurotoxin in your current state."
return
visible_message("<span class='warning'>[src] spits neurotoxin at [target]!</span>", "<span class='alium'>You spit neurotoxin at [target].</span>")
//I'm not motivated enough to revise this. Prjectile code in general needs update.
// Maybe change this to use throw_at? ~ Z
var/turf/T = loc
var/turf/U = (istype(target, /atom/movable) ? target.loc : target)
if(!U || !T)
return
while(U && !istype(U,/turf))
U = U.loc
if(!istype(T, /turf))
return
if (U == T)
usr.bullet_act(new /obj/item/projectile/energy/neurotoxin(usr.loc), get_organ_target())
return
if(!istype(U, /turf))
return
var/obj/item/projectile/energy/neurotoxin/A = new /obj/item/projectile/energy/neurotoxin(usr.loc)
A.current = U
A.yo = U.y - T.y
A.xo = U.x - T.x
A.process()
return
/mob/living/carbon/human/proc/resin() // -- TLE
set name = "Secrete Resin (75)"
set desc = "Secrete tough malleable resin."
set category = "Abilities"
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
if(!choice)
return
if(!check_alien_ability(75,1,O_RESIN))
return
visible_message("<span class='warning'><B>[src] vomits up a thick purple substance and begins to shape it!</B></span>", "<span class='alium'>You shape a [choice].</span>")
switch(choice)
if("resin door")
new /obj/structure/simple_door/resin(loc)
if("resin wall")
new /obj/effect/alien/resin/wall(loc)
if("resin membrane")
new /obj/effect/alien/resin/membrane(loc)
if("resin nest")
new /obj/structure/bed/nest(loc)
return

View File

@@ -1,326 +0,0 @@
//Stand-in until this is made more lore-friendly.
/datum/species/xenos
name = "Xenomorph"
name_plural = "Xenomorphs"
default_language = "Xenomorph"
language = "Hivemind"
unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
hud_type = /datum/hud_data/alien
rarity_value = 3
has_fine_manipulation = 0
siemens_coefficient = 0
gluttonous = 3
brute_mod = 0.5 // Hardened carapace.
burn_mod = 2 // Weak to fire.
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
reagent_tag = IS_XENOS
blood_color = "#05EE05"
flesh_color = "#282846"
gibbed_anim = "gibbed-a"
dusted_anim = "dust-a"
death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
death_sound = 'sound/voice/hiss6.ogg'
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
speech_chance = 100
breath_type = null
poison_type = null
vision_flags = SEE_SELF|SEE_MOBS
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
bump_flag = ALIEN
swap_flags = ~HEAVY
push_flags = (~HEAVY) ^ ROBOT
var/alien_number = 0
var/caste_name = "creature" // Used to update alien name.
var/weeds_heal_rate = 1 // Health regen on weeds.
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
/datum/species/xenos/get_bodytype()
return "Xenomorph"
/datum/species/xenos/get_random_name()
return "alien [caste_name] ([alien_number])"
/datum/species/xenos/can_understand(var/mob/other)
if(istype(other,/mob/living/carbon/alien/larva))
return 1
return 0
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
H.visible_message("<span class='notice'>[H] caresses [target] with its scythe-like arm.</span>", \
"<span class='notice'>You caress [target] with your scythe-like arm.</span>")
/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H)
if(H.mind)
H.mind.assigned_role = "Alien"
H.mind.special_role = "Alien"
alien_number++ //Keep track of how many aliens we've had so far.
H.real_name = "alien [caste_name] ([alien_number])"
H.name = H.real_name
..()
/datum/species/xenos/handle_environment_special(var/mob/living/carbon/human/H)
var/turf/T = H.loc
if(!T) return
var/datum/gas_mixture/environment = T.return_air()
if(!environment) return
if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
if(!regenerate(H))
var/obj/item/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name[O_PLASMA]
P.stored_plasma += weeds_plasma_rate
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
..()
/datum/species/xenos/proc/regenerate(var/mob/living/carbon/human/H)
var/heal_rate = weeds_heal_rate
var/mend_prob = 10
if (!H.resting)
heal_rate = weeds_heal_rate / 3
mend_prob = 1
//first heal damages
if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
H.adjustBruteLoss(-heal_rate)
H.adjustFireLoss(-heal_rate)
H.adjustOxyLoss(-heal_rate)
H.adjustToxLoss(-heal_rate)
if (prob(5))
H << "<span class='alium'>You feel a soothing sensation come over you...</span>"
return 1
//next internal organs
for(var/obj/item/organ/I in H.internal_organs)
if(I.damage > 0)
I.damage = max(I.damage - heal_rate, 0)
if (prob(5))
H << "<span class='alium'>You feel a soothing sensation within your [I.parent_organ]...</span>"
return 1
//next mend broken bones, approx 10 ticks each
for(var/obj/item/organ/external/E in H.bad_external_organs)
if (E.status & ORGAN_BROKEN)
if (prob(mend_prob))
if (E.mend_fracture())
H << "<span class='alium'>You feel something mend itself inside your [E.name].</span>"
return 1
return 0
/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H)
H.AddInfectionImages()
..()
/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H)
H.RemoveInfectionImages()
..()
/datum/species/xenos/drone
name = "Xenomorph Drone"
caste_name = "drone"
weeds_plasma_rate = 15
slowdown = 1
tail = "xenos_drone_tail"
rarity_value = 5
icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/evolve,
/mob/living/carbon/human/proc/resin,
/mob/living/carbon/human/proc/corrosive_acid
)
/datum/species/xenos/drone/handle_post_spawn(var/mob/living/carbon/human/H)
var/mob/living/carbon/human/A = H
if(!istype(A))
return ..()
..()
/datum/species/xenos/hunter
name = "Xenomorph Hunter"
weeds_plasma_rate = 5
caste_name = "hunter"
slowdown = -2
total_health = 150
tail = "xenos_hunter_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/hunter,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate
)
/datum/species/xenos/sentinel
name = "Xenomorph Sentinel"
weeds_plasma_rate = 10
caste_name = "sentinel"
slowdown = 0
total_health = 125
tail = "xenos_sentinel_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/sentinel,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin
)
/datum/species/xenos/queen
name = "Xenomorph Queen"
total_health = 250
weeds_heal_rate = 5
weeds_plasma_rate = 20
caste_name = "queen"
slowdown = 4
tail = "xenos_queen_tail"
rarity_value = 10
icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_EGG = /obj/item/organ/internal/xenos/eggsac,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/lay_egg,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin,
/mob/living/carbon/human/proc/resin
)
/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H)
..()
// Make sure only one official queen exists at any point.
if(!alien_queen_exists(1,H))
H.real_name = "alien queen ([alien_number])"
H.name = H.real_name
else
H.real_name = "alien princess ([alien_number])"
H.name = H.real_name
/datum/hud_data/alien
icon = 'icons/mob/screen1_alien.dmi'
has_a_intent = 1
has_m_intent = 1
has_warnings = 1
has_hands = 1
has_drop = 1
has_throw = 1
has_resist = 1
has_pressure = 0
has_nutrition = 0
has_bodytemp = 0
has_internals = 0
gear = list(
"o_clothing" = list("loc" = ui_belt, "name" = "Suit", "slot" = slot_wear_suit, "state" = "equip", "dir" = SOUTH),
"head" = list("loc" = ui_id, "name" = "Hat", "slot" = slot_head, "state" = "hair"),
"storage1" = list("loc" = ui_storage1, "name" = "Left Pocket", "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "name" = "Right Pocket", "slot" = slot_r_store, "state" = "pocket"),
)

View File

@@ -1,49 +0,0 @@
proc/create_new_xenomorph(var/alien_caste,var/target)
target = get_turf(target)
if(!target || !alien_caste) return
var/mob/living/carbon/human/new_alien = new(target)
new_alien.set_species("Xenomorph [alien_caste]")
return new_alien
/mob/living/carbon/human/xdrone/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Drone")
/mob/living/carbon/human/xsentinel/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Sentinel")
/mob/living/carbon/human/xhunter/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Hunter")
/mob/living/carbon/human/xqueen/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Queen")
// I feel like we should generalize/condense down all the various icon-rendering antag procs.
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/mob/living/carbon/human/proc/AddInfectionImages()
if (client)
for (var/mob/living/C in mob_list)
if(C.status_flags & XENO_HOST)
var/obj/item/alien_embryo/A = locate() in C
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
client.images += I
return
/*----------------------------------------
Proc: RemoveInfectionImages()
Des: Removes all infected images from the alien.
----------------------------------------*/
/mob/living/carbon/human/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)
return

View File

@@ -22,7 +22,6 @@
var/obj/item/inventory_head
var/obj/item/inventory_back
var/facehugger
//IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Ian
@@ -124,12 +123,6 @@
if(back_icon)
overlays += back_icon
if(facehugger)
if(istype(src, /mob/living/simple_animal/corgi/puppy))
overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
else
overlays += image('icons/mob/mask.dmi',"facehugger_corgi")
return

View File

@@ -14,6 +14,18 @@
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/slime/science
name = "Kendrick"
colour = "rainbow"
icon_state = "rainbow baby slime"
icon_living = "rainbow baby slime"
icon_dead = "rainbow baby slime dead"
/mob/living/simple_animal/slime/science/initialize()
..()
overlays.Cut()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime
name = "pet slime"
desc = "A lovable, domesticated slime."
@@ -33,8 +45,7 @@
..()
overlays += "aslime-:33"
/mob/living/simple_animal/slime/adult/death()
/mob/living/simple_animal/adultslime/death()
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
S1.icon_state = "[src.colour] baby slime"
S1.icon_living = "[src.colour] baby slime"

View File

@@ -50,13 +50,6 @@
stance = HOSTILE_STANCE_ATTACK
T = M
break
if(istype(A, /obj/machinery/bot))
var/obj/machinery/bot/B = A
if (B.health > 0)
stance = HOSTILE_STANCE_ATTACK
T = B
break
return T
@@ -101,9 +94,6 @@
var/obj/mecha/M = target_mob
M.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
return M
if(istype(target_mob,/obj/machinery/bot))
var/obj/machinery/bot/B = target_mob
B.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE

View File

@@ -359,10 +359,6 @@
var/obj/mecha/M = target_mob
if (M.occupant)
return (0)
if (istype(target_mob,/obj/machinery/bot))
var/obj/machinery/bot/B = target_mob
if(B.health > 0)
return (0)
return 1
/mob/living/simple_animal/say(var/message)

View File

@@ -505,17 +505,6 @@
namecounts[name] = 1
creatures[name] = O
if(istype(O, /obj/machinery/bot))
var/name = "BOT: [O.name]"
if (names.Find(name))
namecounts[name]++
name = "[name] ([namecounts[name]])"
else
names.Add(name)
namecounts[name] = 1
creatures[name] = O
for(var/mob/M in sortAtom(mob_list))
var/name = M.name
if (names.Find(name))

View File

@@ -1,10 +1,4 @@
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
/proc/isxenomorph(A)
if(istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/H = A
return istype(H.species, /datum/species/xenos)
return 0
/proc/issmall(A)
if(A && istype(A, /mob/living))
var/mob/living/L = A

View File

@@ -103,10 +103,6 @@
name = "Shoulder-length Hair"
icon_state = "hair_b"
longalt
name = "Shoulder-length Hair Alt"
icon_state = "hair_longfringe"
/*longish
name = "Longer Hair"
icon_state = "hair_b2"*/
@@ -115,10 +111,6 @@
name = "Long Hair"
icon_state = "hair_vlong"
longeralt
name = "Long Hair Alt"
icon_state = "hair_vlongfringe"
longest
name = "Very Long Hair"
icon_state = "hair_longest"
@@ -482,7 +474,7 @@
name = "Shaved"
icon_state = "bald"
gender = NEUTER
species_allowed = list("Human","Unathi","Tajara","Skrell","Vox","Machine","Teshari")
species_allowed = list("Human","Unathi","Tajara","Skrell", "Machine","Teshari")
teshari_beard
name = "Teshari Beard"
@@ -677,11 +669,6 @@
icon_state = "hair_messy"
species_allowed = list("Tajara")
vox_quills_short
name = "Short Vox Quills"
icon_state = "vox_shortquills"
species_allowed = list("Vox")
/datum/sprite_accessory/facial_hair
taj_sideburns

View File

@@ -161,30 +161,6 @@
qdel(src)
return O
//human -> alien
/mob/living/carbon/human/proc/Alienize()
if (transforming)
return
for(var/obj/item/W in src)
drop_from_inventory(W)
regenerate_icons()
transforming = 1
canmove = 0
icon = null
invisibility = 101
for(var/t in organs)
qdel(t)
var/alien_caste = pick("Hunter","Sentinel","Drone")
var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc)
new_xeno.a_intent = I_HURT
new_xeno.key = key
new_xeno << "<B>You are now an alien.</B>"
qdel(src)
return
/mob/living/carbon/human/proc/slimeize(adult as num, reproduce as num)
if (transforming)
return

View File

@@ -56,6 +56,3 @@
if(owner && owner.stat != DEAD && !is_broken())
backup_time = world.time
if(owner.mind) backup = owner.mind
/obj/item/organ/internal/stack/vox/stack
name = "vox cortical stack"

View File

@@ -1326,9 +1326,6 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/head/seromi
eye_icon = "eyes_seromi"
/obj/item/organ/external/head/vox
eye_icon = "vox_eyes_s"
/obj/item/organ/external/head/no_eyes
eye_icon = "blank_eyes"

View File

@@ -1,52 +0,0 @@
//XENOMORPH ORGANS
/obj/item/organ/internal/xenos
name = "xeno organ"
icon = 'icons/effects/blood.dmi'
desc = "It smells like an accident in a chemical factory."
/obj/item/organ/internal/xenos/eggsac
name = "egg sac"
parent_organ = BP_GROIN
icon_state = "xgibmid1"
organ_tag = O_EGG
/obj/item/organ/internal/xenos/plasmavessel
name = "plasma vessel"
parent_organ = BP_TORSO
icon_state = "xgibdown1"
organ_tag = O_PLASMA
var/stored_plasma = 0
var/max_plasma = 500
/obj/item/organ/internal/xenos/plasmavessel/queen
name = "bloated plasma vessel"
stored_plasma = 200
max_plasma = 500
/obj/item/organ/internal/xenos/plasmavessel/sentinel
stored_plasma = 100
max_plasma = 250
/obj/item/organ/internal/xenos/plasmavessel/hunter
name = "tiny plasma vessel"
stored_plasma = 100
max_plasma = 150
/obj/item/organ/internal/xenos/acidgland
name = "acid gland"
parent_organ = BP_HEAD
icon_state = "xgibtorso"
organ_tag = O_ACID
/obj/item/organ/internal/xenos/hivenode
name = "hive node"
parent_organ = BP_TORSO
icon_state = "xgibmid2"
organ_tag = O_HIVE
/obj/item/organ/internal/xenos/resinspinner
name = "resin spinner"
parent_organ = BP_HEAD
icon_state = "xgibmid2"
organ_tag = O_RESIN

View File

@@ -1,4 +1,4 @@
//Vox pinning weapon.
// Alien pinning weapon.
/obj/item/weapon/gun/launcher/spikethrower
name = "spike thrower"
@@ -37,14 +37,6 @@
/obj/item/weapon/gun/launcher/spikethrower/update_icon()
icon_state = "spikethrower[spikes]"
/obj/item/weapon/gun/launcher/spikethrower/special_check(user)
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(H.species && H.species.get_bodytype() != "Vox")
user << "<span class='warning'>\The [src] does not respond to you!</span>"
return 0
return ..()
/obj/item/weapon/gun/launcher/spikethrower/update_release_force()
return

View File

@@ -26,7 +26,7 @@
item_state = "bolt"
/obj/item/weapon/arrow/quill
name = "vox quill"
name = "alien quill"
desc = "A wickedly barbed quill from some bizarre animal."
icon = 'icons/obj/weapons.dmi'
icon_state = "quill"
@@ -116,7 +116,7 @@
//double check that the user hasn't removed the bolt in the meantime
if(!(bolt && tension && loc == current_user))
return
tension++
update_icon()

View File

@@ -6,7 +6,7 @@
embed = 1 //the dart is shot fast enough to pierce space suits, so I guess splintering inside the target can be a thing. Should be rare due to low damage.
var/reagent_amount = 15
kill_count = 15 //shorter range
muzzle_type = null
/obj/item/projectile/bullet/chemdart/New()
@@ -194,13 +194,3 @@
unload_ammo(usr)
src.updateUsrDialog()
return
/obj/item/weapon/gun/projectile/dartgun/vox
name = "alien dart gun"
desc = "A small gas-powered dartgun, fitted for nonhuman hands."
/obj/item/weapon/gun/projectile/dartgun/vox/medical
starting_chems = list("kelotane","bicaridine","anti_toxin")
/obj/item/weapon/gun/projectile/dartgun/vox/raider
starting_chems = list("space_drugs","stoxin","impedrezene")

View File

@@ -32,8 +32,6 @@
var/options = list("robot", "slime")
for(var/t in all_species)
options += t
options -= "Xenomorph Queen"
options -= "Xenomorph"
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species)

View File

@@ -178,11 +178,8 @@
W.visible_message("<span class='notice'>The fungi are completely dissolved by the solution!</span>")
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
if(istype(O, /obj/effect/alien/weeds/))
var/obj/effect/alien/weeds/alien_weeds = O
alien_weeds.health -= rand(15, 35)
alien_weeds.healthcheck()
else if(istype(O, /obj/effect/plant))
..()
if(istype(O, /obj/effect/plant))
qdel(O)
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)

View File

@@ -42,7 +42,8 @@
var/trans = reagents.trans_to_obj(target, amount_per_transfer_from_this)
user << "<span class='notice'>You add [trans] units of the condiment to \the [target].</span>"
else(..())
else
..()
feed_sound(var/mob/user)
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)

View File

@@ -1,4 +1,4 @@
/obj/machinery/computer/shuttle_control/multi/vox
/obj/machinery/computer/shuttle_control/multi/skipjack
name = "skipjack control console"
req_access = list(access_syndicate)
shuttle_tag = "Skipjack"

View File

@@ -12,46 +12,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.open == (affected.encased ? 3 : 2)
//////////////////////////////////////////////////////////////////
// ALIEN EMBRYO SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/internal/remove_embryo
allowed_tools = list(
/obj/item/weapon/hemostat = 100, \
/obj/item/weapon/wirecutters = 75, \
/obj/item/weapon/material/kitchen/utensil/fork = 20
)
blood_level = 2
min_duration = 80
max_duration = 100
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/embryo = 0
for(var/obj/item/alien_embryo/A in target)
embryo = 1
break
if (!hasorgans(target))
return
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return ..() && affected && embryo && affected.open == 3 && target_zone == BP_TORSO
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
user.visible_message(msg, self_msg)
target.custom_pain("Something hurts horribly in your chest!",1)
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("<span class='warning'>[user] rips the larva out of [target]'s ribcage!</span>",
"You rip the larva out of [target]'s ribcage!")
for(var/obj/item/alien_embryo/A in target)
A.loc = A.loc.loc
//////////////////////////////////////////////////////////////////
// CHEST INTERNAL ORGAN SURGERY //
//////////////////////////////////////////////////////////////////

View File

@@ -89,7 +89,6 @@ h1.alert, h2.alert {color: #000000;}
.soghun {color: #228B22;}
.solcom {color: #22228B;}
.changeling {color: #800080;}
.vox {color: #AA00AA;}
.rough {font-family: "Trebuchet MS", cursive, sans-serif;}
.say_quote {font-family: Georgia, Verdana, sans-serif;}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

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