Cherrypicked xenophage-rewrite mechanics over.

This commit is contained in:
Zuhayr
2015-09-21 20:36:45 +09:30
parent 7d7f0da2ca
commit 22ef779f65
35 changed files with 7326 additions and 8070 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 ccorrosive 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'>[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!</B>")
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()
@@ -0,0 +1,66 @@
/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/blob_act()
health-=50
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
+80
View File
@@ -0,0 +1,80 @@
#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/process()
if(progress < MAX_PROGRESS)
progress++
if(progress == MAX_PROGRESS)
src << "todo alert goasts"
update_icon()
return
// Max progress, cancel processing.
processing_objects -= src
/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)
// Check for bans properly.
if(jobban_isbanned(user, "Xenomorph"))
user << "<span class='danger'>You are banned from playing a Xenomorph.</span>"
return
if(progress == -1) //Egg has been hatched.
return
else if(progress < MAX_PROGRESS)
user << "\The [src] has not yet matured."
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
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!")
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
@@ -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