Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into attack-cleanup2

Conflicts:
	code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
This commit is contained in:
mwerezak
2015-10-15 07:08:16 -04:00
183 changed files with 3686 additions and 5077 deletions
+13 -406
View File
@@ -1,276 +1,11 @@
/* 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/blob_act()
health-=50
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/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
/obj/effect/acid
name = "acid"
desc = "Burbling corrossive stuff. I wouldn't want to touch it."
desc = "Burbling corrosive stuff. Probably a bad idea to roll around in it."
icon_state = "acid"
icon = 'icons/mob/alien.dmi'
density = 0
opacity = 0
@@ -280,9 +15,9 @@ Alien plants should do something if theres a lot of poison
var/ticks = 0
var/target_strength = 0
/obj/effect/alien/acid/New(loc, target)
/obj/effect/acid/New(loc, supplied_target)
..(loc)
src.target = target
target = supplied_target
if(isturf(target)) // Turf take twice as long to take down.
target_strength = 8
@@ -290,17 +25,13 @@ Alien plants should do something if theres a lot of poison
target_strength = 4
tick()
/obj/effect/alien/acid/proc/tick()
/obj/effect/acid/proc/tick()
if(!target)
qdel(src)
ticks += 1
ticks++
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)
target.visible_message("<span class='alium'>\The [target] collapses under its own weight into a puddle of goop and undigested debris!</span>")
if(istype(target, /turf/simulated/wall)) // I hate turf code.
var/turf/simulated/wall/W = target
W.dismantle_wall(1)
@@ -311,135 +42,11 @@ Alien plants should do something if theres a lot of poison
switch(target_strength - ticks)
if(6)
visible_message("<span class='alium'>[src.target] is holding up against the acid!</span>")
visible_message("<span class='alium'>\The [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>")
visible_message("<span class='alium'>\The [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>")
visible_message("<span class='alium'>\The [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/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)
visible_message("<span class='alium'>\The [src.target] begins to crumble under the acid!</span>")
spawn(rand(150, 200)) tick()
-3
View File
@@ -150,9 +150,6 @@
/obj/structure/foamedmetal/ex_act(severity)
qdel(src)
/obj/structure/foamedmetal/blob_act()
qdel(src)
/obj/structure/foamedmetal/bullet_act()
if(metal == 1 || prob(50))
qdel(src)
-4
View File
@@ -52,10 +52,6 @@
prisonsecuritywarp += loc
qdel(src)
return
if("blobstart")
blobstart += loc
qdel(src)
return
if("xeno_spawn")
xeno_spawn += loc
qdel(src)
@@ -105,27 +105,61 @@
qdel(src)
*/
/client/proc/spawn_tanktransferbomb()
set category = "Debug"
set desc = "Spawn a tank transfer valve bomb"
set name = "Instant TTV"
if(!check_rights(R_SPAWN)) return
var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
var/p = input("Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt)) as num|null
if(p == null) return
var/o = input("Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt)) as num|null
if(o == null) return
var/c = input("Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt)) as num|null
if(c == null) return
new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
/obj/effect/spawner/newbomb
name = "bomb"
name = "TTV bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
var/btype = 0 // 0=radio, 1=prox, 2=time
var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 10.96
var/oxygen_amt = 16.44
var/carbon_amt = 0.0
timer
btype = 2
/obj/effect/spawner/newbomb/timer
name = "TTV bomb - timer"
assembly_type = /obj/item/device/assembly/timer
syndicate
/obj/effect/spawner/newbomb/timer/syndicate
name = "TTV bomb - merc"
//High yield bombs. Yes, it is possible to make these with toxins
phoron_amt = 15.66
oxygen_amt = 24.66
proximity
btype = 1
/obj/effect/spawner/newbomb/proximity
name = "TTV bomb - proximity"
assembly_type = /obj/item/device/assembly/prox_sensor
radio
btype = 0
/obj/effect/spawner/newbomb/New()
/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
if(ph != null) phoron_amt = ph
if(ox != null) oxygen_amt = ox
if(co != null) carbon_amt = co
..()
/obj/effect/spawner/newbomb/New(newloc)
..(newloc)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
@@ -137,28 +171,15 @@
OT.master = V
PT.air_contents.temperature = PHORON_FLASHPOINT
PT.air_contents.adjust_multi("phoron", 12, "carbon_dioxide", 8)
PT.air_contents.gas["phoron"] = phoron_amt
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
PT.air_contents.update_values()
OT.air_contents.temperature = PHORON_FLASHPOINT
OT.air_contents.adjust_gas("oxygen", 20)
OT.air_contents.gas["oxygen"] = oxygen_amt
OT.air_contents.update_values()
var/obj/item/device/assembly/S
switch (src.btype)
// radio
if (0)
S = new/obj/item/device/assembly/signaler(V)
// proximity
if (1)
S = new/obj/item/device/assembly/prox_sensor(V)
// timer
if (2)
S = new/obj/item/device/assembly/timer(V)
var/obj/item/device/assembly/S = new assembly_type(V)
V.attached_device = S
-3
View File
@@ -108,9 +108,6 @@
else
return
/obj/item/blob_act()
return
//user: The mob that is suiciding
//damagetype: The type of damage the item will inflict on the user
//BRUTELOSS = 1
@@ -15,7 +15,7 @@
//
// HOW TO REFILL THE DEVICE
//
// It will need to be manually refilled with lights.
// It can be manually refilled or by clicking on a storage item containing lights.
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
//
// EMAGGED FEATURES
@@ -41,7 +41,7 @@
/obj/item/device/lightreplacer
name = "light replacer"
desc = "A device to automatically replace lights. Refill with working lightbulbs."
desc = "A device to automatically replace lights. Refill with working lightbulbs or sheets of glass."
icon = 'icons/obj/janitor.dmi'
icon_state = "lightreplacer0"
@@ -51,14 +51,13 @@
slot_flags = SLOT_BELT
origin_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 2)
var/max_uses = 20
var/uses = 0
var/max_uses = 32
var/uses = 32
var/emagged = 0
var/failmsg = ""
var/charge = 0
/obj/item/device/lightreplacer/New()
uses = max_uses / 2
failmsg = "The [name]'s refill light blinks red."
..()
@@ -73,8 +72,8 @@
user << "<span class='warning'>[src.name] is full.</span>"
return
else if(G.use(1))
AddUses(5)
user << "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] lights remaining.</span>"
AddUses(16) //Autolathe converts 1 sheet into 16 lights.
user << "<span class='notice'>You insert a piece of glass into \the [src.name]. You have [uses] light\s remaining.</span>"
return
else
user << "<span class='warning'>You need one sheet of glass to replace lights.</span>"
@@ -84,7 +83,7 @@
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
AddUses(1)
user << "You insert the [L.name] into the [src.name]. You have [uses] lights remaining."
user << "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining."
user.drop_item()
qdel(L)
return
@@ -92,7 +91,6 @@
user << "You need a working light."
return
/obj/item/device/lightreplacer/attack_self(mob/user)
/* // This would probably be a bit OP. If you want it though, uncomment the code.
if(isrobot(user))
@@ -100,17 +100,9 @@
if (src.loc != usr)
return 0
if(tank_one && href_list["tankone"])
split_gases()
valve_open = 0
tank_one.loc = get_turf(src)
tank_one = null
update_icon()
remove_tank(tank_one)
else if(tank_two && href_list["tanktwo"])
split_gases()
valve_open = 0
tank_two.loc = get_turf(src)
tank_two = null
update_icon()
remove_tank(tank_two)
else if(href_list["open"])
toggle_valve()
else if(attached_device)
@@ -149,20 +141,43 @@
if(attached_device)
overlays += "device"
/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
if(tank_one == T)
split_gases()
tank_one = null
else if(tank_two == T)
split_gases()
tank_two = null
else
return
T.loc = get_turf(src)
update_icon()
/obj/item/device/transfer_valve/proc/merge_gases()
if(valve_open)
return
tank_two.air_contents.volume += tank_one.air_contents.volume
var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1)
tank_two.air_contents.merge(temp)
valve_open = 1
/obj/item/device/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
if(!valve_open)
return
valve_open = 0
if(deleted(tank_one) || deleted(tank_two))
return
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp)
tank_two.air_contents.volume -= tank_one.air_contents.volume
/*
Exadv1: I know this isn't how it's going to work, but this was just to check
@@ -170,8 +185,7 @@
*/
/obj/item/device/transfer_valve/proc/toggle_valve()
if(valve_open==0 && (tank_one && tank_two))
valve_open = 1
if(!valve_open && (tank_one && tank_two))
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
@@ -197,16 +211,11 @@
message_admins(log_str, 0, 1)
log_game(log_str)
merge_gases()
spawn(20) // In case one tank bursts
for (var/i=0,i<5,i++)
src.update_icon()
sleep(10)
src.update_icon()
else if(valve_open==1 && (tank_one && tank_two))
split_gases()
valve_open = 0
src.update_icon()
src.update_icon()
// this doesn't do anything but the timer etc. expects it to be here
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
+7 -6
View File
@@ -137,6 +137,7 @@
if (istype(O, /obj/item/stack))
var/obj/item/stack/S = O
S.amount = produced
S.add_to_stacks(user)
if (istype(O, /obj/item/weapon/storage)) //BubbleWrap - so newly formed boxes are empty
for (var/obj/item/I in O)
@@ -191,7 +192,7 @@
else
if(get_amount() < used)
return 0
for(var/i = 1 to uses_charge)
for(var/i = 1 to charge_costs.len)
var/datum/matter_synth/S = synths[i]
S.use_charge(charge_costs[i] * used) // Doesn't need to be deleted
return 1
@@ -264,8 +265,8 @@
return 0
var/datum/matter_synth/S = synths[1]
. = round(S.get_charge() / charge_costs[1])
if(uses_charge > 1)
for(var/i = 2 to uses_charge)
if(charge_costs.len > 1)
for(var/i = 2 to charge_costs.len)
S = synths[i]
. = min(., round(S.get_charge() / charge_costs[i]))
return
@@ -284,13 +285,13 @@
return
return max_amount
/obj/item/stack/proc/add_to_stacks(mob/usr as mob)
for (var/obj/item/stack/item in usr.loc)
/obj/item/stack/proc/add_to_stacks(mob/user as mob)
for (var/obj/item/stack/item in user.loc)
if (item==src)
continue
var/transfer = src.transfer_to(item)
if (transfer)
usr << "You add a new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s."
user << "<span class='notice'>You add a new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s.</span>"
if(!amount)
break
@@ -0,0 +1,31 @@
#ifndef T_BOARD
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/weapon/circuitboard/holodeckcontrol
name = T_BOARD("holodeck control console")
build_path = /obj/machinery/computer/HolodeckControl
origin_tech = "programming=2;bluespace=2"
var/last_to_emag
var/linkedholodeck_area
var/list/supported_programs
var/list/restricted_programs
/obj/item/weapon/circuitboard/holodeckcontrol/construct(var/obj/machinery/computer/HolodeckControl/HC)
if (..(HC))
HC.supported_programs = supported_programs.Copy()
HC.restricted_programs = restricted_programs.Copy()
if(linkedholodeck_area)
HC.linkedholodeck = locate(linkedholodeck_area)
if(last_to_emag)
HC.last_to_emag = last_to_emag
HC.emagged = 1
HC.safety_disabled = 1
/obj/item/weapon/circuitboard/holodeckcontrol/deconstruct(var/obj/machinery/computer/HolodeckControl/HC)
if (..(HC))
linkedholodeck_area = HC.linkedholodeck_area
supported_programs = HC.supported_programs.Copy()
restricted_programs = HC.restricted_programs.Copy()
last_to_emag = HC.last_to_emag
HC.emergencyShutdown()
@@ -224,7 +224,7 @@
//Set the stop_messages to stop it from printing messages
/obj/item/weapon/storage/proc/can_be_inserted(obj/item/W as obj, stop_messages = 0)
if(!istype(W)) return //Not an item
if(!usr.canUnEquip(W))
return 0
@@ -340,6 +340,21 @@
if(isrobot(user))
return //Robots can't interact with storage items.
if(istype(W, /obj/item/device/lightreplacer))
var/obj/item/device/lightreplacer/LP = W
var/amt_inserted = 0
var/turf/T = get_turf(user)
for(var/obj/item/weapon/light/L in src.contents)
if(L.status == 0)
if(LP.uses < LP.max_uses)
LP.AddUses(1)
amt_inserted++
remove_from_storage(L, T)
qdel(L)
if(amt_inserted)
user << "You inserted [amt_inserted] light\s into \the [LP.name]. You have [LP.uses] light\s remaining."
return
if(!can_be_inserted(W))
return
+12 -13
View File
@@ -41,6 +41,10 @@
processing_objects.Remove(src)
if(istype(loc, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TTV = loc
TTV.remove_tank(src)
..()
/obj/item/weapon/tank/examine(mob/user)
@@ -63,17 +67,6 @@
descriptive = "cold"
user << "<span class='notice'>\The [src] feels [descriptive].</span>"
/obj/item/weapon/tank/blob_act()
if(prob(50))
var/turf/location = src.loc
if (!( istype(location, /turf) ))
qdel(src)
if(src.air_contents)
location.assume_air(air_contents)
qdel(src)
/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(src.loc, /obj/item/assembly))
@@ -260,7 +253,10 @@
qdel(src)
else if(pressure > TANK_RUPTURE_PRESSURE)
//world << "<span class='notice'>[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]</span>"
#ifdef FIREDBG
log_debug("<span class='warning'>[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]</span>")
#endif
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
@@ -272,7 +268,10 @@
integrity--
else if(pressure > TANK_LEAK_PRESSURE)
//world << "<span class='notice'>[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]</span>"
#ifdef FIREDBG
log_debug("<span class='warning'>[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]</span>")
#endif
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
@@ -180,10 +180,6 @@
health = 0
healthcheck()
/obj/effect/energy_net/blob_act()
health = 0
healthcheck()
/obj/effect/energy_net/attack_hand(var/mob/user)
var/mob/living/carbon/human/H = user
+5 -1
View File
@@ -46,7 +46,11 @@
/obj/proc/CouldUseTopic(var/mob/user)
var/atom/host = nano_host()
host.add_hiddenprint(user)
if(!isAI(user) && host.Adjacent(user))
// We are -probably- in physical contact with the object, better than how Topics() previously did it and always applied fingerprints.
host.add_fingerprint(user)
else
host.add_hiddenprint(user)
/obj/proc/CouldNotUseTopic(var/mob/user)
// Nada
-4
View File
@@ -28,10 +28,6 @@
return ..()
/obj/structure/blob_act()
if(prob(50))
qdel(src)
/obj/structure/attack_tk()
return
@@ -0,0 +1,61 @@
/obj/structure/alien
name = "alien thing"
desc = "There's something alien about this."
icon = 'icons/mob/alien.dmi'
var/health = 50
/obj/structure/alien/proc/healthcheck()
if(health <=0)
density = 0
qdel(src)
return
/obj/structure/alien/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
return
/obj/structure/alien/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/structure/alien/hitby(AM as mob|obj)
..()
visible_message("<span class='danger'>\The [src] was hit by \the [AM].</span>")
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/structure/alien/attack_generic()
attack_hand(usr)
/obj/structure/alien/attackby(var/obj/item/weapon/W, var/mob/user)
health = max(0, health - W.force)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
healthcheck()
..()
return
/obj/structure/alien/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
+96
View File
@@ -0,0 +1,96 @@
#define MAX_PROGRESS 100
/obj/structure/alien/egg
desc = "It looks like a weird egg."
name = "egg"
icon_state = "egg_growing"
density = 0
anchored = 1
var/progress = 0
/obj/structure/alien/egg/New()
..()
processing_objects += src
/obj/structure/alien/egg/Destroy()
processing_objects -= src
..()
/obj/structure/alien/egg/CanUseTopic(var/mob/user)
return isobserver(user) ? STATUS_INTERACTIVE : STATUS_CLOSE
/obj/structure/alien/egg/Topic(href, href_list)
if(..())
return 1
if(href_list["spawn"])
attack_ghost(usr)
/obj/structure/alien/egg/process()
progress++
if(progress >= MAX_PROGRESS)
for(var/mob/M in dead_mob_list)
if(istype(M,/mob/dead) && M.client && M.client.prefs && (M.client.prefs.be_special & BE_ALIEN))
M << "<span class='notice'>An alien is ready to hatch! ([ghost_follow_link(src, M)]) (<a href='byond://?src=\ref[src];spawn=1'>spawn</a>)</span>"
processing_objects -= src
update_icon()
/obj/structure/alien/egg/update_icon()
if(progress == -1)
icon_state = "egg_hatched"
else if(progress < MAX_PROGRESS)
icon_state = "egg_growing"
else
icon_state = "egg"
/obj/structure/alien/egg/attack_ghost(var/mob/dead/observer/user)
if(progress == -1) //Egg has been hatched.
return
if(progress < MAX_PROGRESS)
user << "\The [src] has not yet matured."
return
if(!user.MayRespawn(1))
return
// Check for bans properly.
if(jobban_isbanned(user, "Xenomorph"))
user << "<span class='danger'>You are banned from playing a Xenomorph.</span>"
return
var/confirm = alert(user, "Are you sure you want to join as a Xenomorph larva?", "Become Larva", "No", "Yes")
if(!src || confirm != "Yes")
return
if(!user || !user.ckey)
return
if(progress == -1) //Egg has been hatched.
user << "Too slow..."
return
flick("egg_opening",src)
progress = -1 // No harvesting pls.
sleep(5)
if(!src || !user)
visible_message("<span class='alium'>\The [src] writhes with internal motion, but nothing comes out.</span>")
progress = MAX_PROGRESS // Someone else can have a go.
return // What a pain.
// Create the mob, transfer over key.
var/mob/living/carbon/alien/larva/larva = new(get_turf(src))
larva.ckey = user.ckey
spawn(-1)
if(user) qdel(user) // Remove the keyless ghost if it exists.
visible_message("<span class='alium'>\The [src] splits open with a wet slithering noise, and \the [larva] writhes free!</span>")
// Turn us into a hatched egg.
name = "hatched alien egg"
desc += " This one has hatched."
update_icon()
#undef MAX_PROGRESS
@@ -0,0 +1,19 @@
/obj/structure/alien/node
name = "alien weed node"
desc = "Some kind of strange, pulsating structure."
icon_state = "weednode"
health = 100
layer = 3.1
/obj/structure/alien/node/New()
..()
processing_objects += src
/obj/structure/alien/node/Destroy()
processing_objects -= src
..()
/obj/structure/alien/node/process()
if(locate(/obj/effect/plant) in loc)
return
new /obj/effect/plant(get_turf(src), plant_controller.seeds["xenomorph"])
@@ -0,0 +1,50 @@
/obj/structure/alien/resin
name = "resin"
desc = "Looks like some kind of slimy growth."
icon_state = "resin"
density = 1
opacity = 1
anchored = 1
health = 200
/obj/structure/alien/resin/wall
name = "resin wall"
desc = "Purple slime solidified into a wall."
icon_state = "resinwall"
/obj/structure/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/structure/alien/resin/New()
..()
var/turf/T = get_turf(src)
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/structure/alien/resin/Destroy()
var/turf/T = get_turf(src)
T.thermal_conductivity = initial(T.thermal_conductivity)
..()
/obj/structure/alien/resin/attack_hand(var/mob/user)
if (HULK in user.mutations)
visible_message("<span class='danger'>\The [user] destroys \the [name]!</span>")
health = 0
else
// Aliens can get straight through these.
if(istype(user,/mob/living/carbon))
var/mob/living/carbon/M = user
if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)
visible_message("<span class='alium'>\The [user] strokes \the [name] and it melts away!</span>")
health = 0
healthcheck()
return
visible_message("<span class='danger'>\The [user] claws at \the [src]!</span>")
// Todo check attack datums.
health -= rand(5,10)
healthcheck()
return
@@ -196,13 +196,6 @@
return
// this should probably use dump_contents()
/obj/structure/closet/blob_act()
if(prob(75))
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.loc)
qdel(src)
/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(src.opened)
if(istype(W, /obj/item/weapon/grab))
@@ -96,10 +96,6 @@
for(var/mob/M in src)
shatter(M)
/obj/structure/closet/statue/blob_act()
for(var/mob/M in src)
shatter(M)
/obj/structure/closet/statue/ex_act(severity)
for(var/mob/M in src)
M.ex_act(severity)
@@ -34,15 +34,6 @@
src.healthcheck()
return
/obj/structure/displaycase/blob_act()
if (prob(75))
new /obj/item/weapon/material/shard( src.loc )
if (occupied)
new /obj/item/weapon/gun/energy/captain( src.loc )
occupied = 0
qdel(src)
/obj/structure/displaycase/proc/healthcheck()
if (src.health <= 0)
if (!( src.destroyed ))
-4
View File
@@ -202,10 +202,6 @@
return
return ..()
/obj/structure/girder/blob_act()
if(prob(40))
qdel(src)
/obj/structure/girder/ex_act(severity)
switch(severity)
-3
View File
@@ -16,9 +16,6 @@
/obj/structure/grille/ex_act(severity)
qdel(src)
/obj/structure/grille/blob_act()
qdel(src)
/obj/structure/grille/update_icon()
if(destroyed)
icon_state = "[initial(icon_state)]-b"
@@ -60,9 +60,6 @@
deflate(1)
return
/obj/structure/inflatable/blob_act()
deflate(1)
/obj/structure/inflatable/attack_hand(mob/user as mob)
add_fingerprint(user)
return
@@ -1,94 +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/blob_act()
if (prob(75))
new /obj/item/weapon/material/shard( src.loc )
Break()
qdel(src)
/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
-4
View File
@@ -34,10 +34,6 @@
L.updateOverlays(src.loc)
..()
/obj/structure/lattice/blob_act()
qdel(src)
return
/obj/structure/lattice/ex_act(severity)
switch(severity)
if(1.0)
-4
View File
@@ -160,10 +160,6 @@ FLOOR SAFES
return
obj/structure/safe/blob_act()
return
obj/structure/safe/ex_act(severity)
return
-4
View File
@@ -19,10 +19,6 @@
else
return
/obj/structure/sign/blob_act()
qdel(src)
return
/obj/structure/sign/attackby(obj/item/tool as obj, mob/user as mob) //deconstruction
if(istype(tool, /obj/item/weapon/screwdriver) && !istype(src, /obj/structure/sign/double))
user << "You unfasten the sign with your [tool]."
@@ -86,11 +86,6 @@
qdel(src)
return
/obj/structure/bed/blob_act()
if(prob(75))
material.place_sheet(get_turf(src))
qdel(src)
/obj/structure/bed/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
@@ -98,11 +98,6 @@ var/global/list/stool_cache = list() //haha stool
qdel(src)
return
/obj/item/weapon/stool/blob_act()
if(prob(75))
material.place_sheet(get_turf(src))
qdel(src)
/obj/item/weapon/stool/proc/dismantle()
if(material)
material.place_sheet(get_turf(src))
-4
View File
@@ -122,10 +122,6 @@
shatter(0)
return
/obj/structure/window/blob_act()
shatter()
//TODO: Make full windows a separate type of window.
//Once a full window, it will always be a full window, so there's no point
//having the same type for both.