Merge pull request #952 from ZomgPonies/superhero
Massive Superhero Update
@@ -36,6 +36,7 @@ var/global/list/all_species[0]
|
||||
var/global/list/all_languages[0]
|
||||
var/global/list/language_keys[0] // Table of say codes for all languages
|
||||
var/global/list/all_nations[0]
|
||||
var/global/list/all_superheroes[0]
|
||||
var/global/list/whitelisted_species = list()
|
||||
|
||||
//global var of unsafe-to-spawn-on-reaction mobs
|
||||
@@ -141,6 +142,11 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al
|
||||
var/datum/nations/N = new T
|
||||
all_nations[N.name] = N
|
||||
|
||||
paths = typesof(/datum/superheroes)-/datum/superheroes
|
||||
for(var/T in paths)
|
||||
var/datum/superheroes/S = new T
|
||||
all_superheroes[S.name] = S
|
||||
|
||||
//Languages and species.
|
||||
paths = typesof(/datum/language)-/datum/language
|
||||
for(var/T in paths)
|
||||
|
||||
@@ -269,6 +269,7 @@ client
|
||||
body += "<option value='?_src_=vars;makemonkey=\ref[D]'>Make monkey</option>"
|
||||
body += "<option value='?_src_=vars;makealien=\ref[D]'>Make alien</option>"
|
||||
body += "<option value='?_src_=vars;makeslime=\ref[D]'>Make slime</option>"
|
||||
body += "<option value='?_src_=vars;makesuper=\ref[D]'>Make Superhero</option>"
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;gib=\ref[D]'>Gib</option>"
|
||||
if(isobj(D))
|
||||
@@ -764,6 +765,19 @@ client
|
||||
return
|
||||
holder.Topic(href, list("makeslime"=href_list["makeslime"]))
|
||||
|
||||
else if(href_list["makesuper"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makesuper"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
else if(href_list["makeai"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define TARGET_CLOSEST 1
|
||||
#define TARGET_RANDOM 2
|
||||
|
||||
/obj/effect/proc_holder
|
||||
var/panel = "Debug"//What panel the proc holder needs to go on.
|
||||
|
||||
@@ -235,6 +238,9 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
|
||||
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
|
||||
var/include_user = 0 //if it includes usr in the target list
|
||||
var/random_target = 0 // chooses random viable target instead of asking the caster
|
||||
var/random_target_priority = TARGET_CLOSEST // if random_target is enabled how it will pick the target
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/aoe_turf //affects all turfs in view or range (depends)
|
||||
var/inner_radius = -1 //for all your ring spell needs
|
||||
@@ -260,7 +266,26 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
continue
|
||||
possible_targets += M
|
||||
|
||||
targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
|
||||
//targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
|
||||
//Adds a safety check post-input to make sure those targets are actually in range.
|
||||
var/mob/M
|
||||
if(!random_target)
|
||||
M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets
|
||||
else
|
||||
switch(random_target_priority)
|
||||
if(TARGET_RANDOM)
|
||||
M = pick(possible_targets)
|
||||
if(TARGET_CLOSEST)
|
||||
for(var/mob/living/L in possible_targets)
|
||||
if(M)
|
||||
if(get_dist(user,L) < get_dist(user,M))
|
||||
if(los_check(user,L))
|
||||
M = L
|
||||
else
|
||||
if(los_check(user,L))
|
||||
M = L
|
||||
if(M in view_or_range(range, user, selection_type)) targets += M
|
||||
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
for(var/mob/living/target in view_or_range(range, user, selection_type))
|
||||
@@ -300,3 +325,16 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
perform(targets)
|
||||
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/proc/los_check(mob/A,mob/B)
|
||||
//Checks for obstacles from A to B
|
||||
var/obj/dummy = new(A.loc)
|
||||
dummy.pass_flags |= PASSTABLE
|
||||
for(var/turf/turf in getline(A,B))
|
||||
for(var/atom/movable/AM in turf)
|
||||
if(!AM.CanPass(dummy,turf,1))
|
||||
qdel(dummy)
|
||||
return 0
|
||||
qdel(dummy)
|
||||
return 1
|
||||
@@ -0,0 +1,103 @@
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning
|
||||
name = "Lightning Bolt"
|
||||
desc = "Throws a lightning bolt at the nearby enemy. Classic."
|
||||
charge_type = "recharge"
|
||||
charge_max = 300
|
||||
clothes_req = 1
|
||||
invocation = "UN'LTD P'WAH!"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 30
|
||||
selection_type = "view"
|
||||
random_target = 1
|
||||
var/energy = 0
|
||||
var/ready = 0
|
||||
var/image/halo = null
|
||||
icon_power_button = "spell_tech"
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/lightnian
|
||||
clothes_req = 0
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/Click()
|
||||
if(!ready)
|
||||
if(cast_check())
|
||||
StartChargeup()
|
||||
else
|
||||
if(cast_check(skipcharge=1))
|
||||
choose_targets()
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/proc/StartChargeup(mob/user = usr)
|
||||
ready = 1
|
||||
user << "<span class='notice'>You start gathering the power.</span>"
|
||||
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
|
||||
user.overlays.Add(halo)
|
||||
spawn(0)
|
||||
while(ready)
|
||||
sleep(1)
|
||||
energy++
|
||||
if(energy >= 100 && ready)
|
||||
Discharge()
|
||||
|
||||
obj/effect/proc_holder/spell/wizard/targeted/lightning/proc/Reset(mob/user = usr)
|
||||
ready = 0
|
||||
energy = 0
|
||||
if(halo)
|
||||
user.overlays.Remove(halo)
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/revert_cast(mob/user = usr)
|
||||
user << "<span class='notice'>No target found in range.</span>"
|
||||
Reset(user)
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/proc/Discharge(mob/user = usr)
|
||||
var/mob/living/M = user
|
||||
//M.electrocute_act(25,"Lightning Bolt")
|
||||
M << "<span class='danger'>You lose control over the spell.</span>"
|
||||
Reset(user)
|
||||
start_recharge()
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/cast(list/targets, mob/user = usr)
|
||||
|
||||
var/mob/living/carbon/target = targets[1]
|
||||
|
||||
if(get_dist(user,target)>range)
|
||||
user << "<span class='notice'>They are too far away!</span>"
|
||||
Reset(user)
|
||||
return
|
||||
|
||||
user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
|
||||
|
||||
switch(energy)
|
||||
if(0 to 25)
|
||||
target.electrocute_act(10,"Lightning Bolt")
|
||||
playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
if(25 to 75)
|
||||
target.electrocute_act(25,"Lightning Bolt")
|
||||
playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
if(75 to 100)
|
||||
//CHAIN LIGHTNING
|
||||
Bolt(user,target,energy,user)
|
||||
Reset(user)
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/lightning/proc/Bolt(mob/origin,mob/target,bolt_energy,mob/user = usr)
|
||||
origin.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
|
||||
var/mob/living/carbon/current = target
|
||||
if(bolt_energy < 75)
|
||||
current.electrocute_act(25,"Lightning Bolt")
|
||||
playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
else
|
||||
current.electrocute_act(25,"Lightning Bolt")
|
||||
playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
var/list/possible_targets = new
|
||||
for(var/mob/living/M in view_or_range(range,target,"view"))
|
||||
if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not
|
||||
continue
|
||||
possible_targets += M
|
||||
if(!possible_targets.len)
|
||||
return
|
||||
var/mob/living/next = pick(possible_targets)
|
||||
if(next)
|
||||
Bolt(current,next,bolt_energy-6,user) // 5 max bounces
|
||||
@@ -266,6 +266,104 @@
|
||||
SA.health -= 20
|
||||
..()
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas
|
||||
name = "bolas"
|
||||
desc = "An entangling bolas. Throw at your foes to trip them and prevent them from running."
|
||||
gender = NEUTER
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_override = 'icons/mob/in-hand/swords.dmi'
|
||||
icon_state = "bolas"
|
||||
siemens_coefficient = 1
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 2
|
||||
w_class = 2
|
||||
origin_tech = "materials=1"
|
||||
attack_verb = list("lashed", "bludgeoned", "whipped")
|
||||
force = 4
|
||||
breakouttime = 50 //10 seconds
|
||||
throw_speed = 1
|
||||
throw_range = 10
|
||||
var/dispenser = 0
|
||||
var/throw_sound = 'sound/weapons/whip.ogg'
|
||||
var/trip_prob = 60
|
||||
var/thrown_from
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas/suicide_act(mob/living/user)
|
||||
viewers(user) << "<span class='danger'>[user] is wrapping the [src.name] around \his neck! It looks like \he's trying to commit suicide.</span>"
|
||||
return(OXYLOSS)
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas/throw_at(var/atom/A, throw_range, throw_speed)
|
||||
if(usr && !istype(thrown_from, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas)) //if there is a user, but not a mech
|
||||
if(istype(usr, /mob/living/carbon/human)) //if the user is human
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if((CLUMSY in H.mutations) && prob(50))
|
||||
H <<"<span class='warning'>You smack yourself in the face while swinging the [src]!</span>"
|
||||
H.Stun(2)
|
||||
H.drop_item(src)
|
||||
return
|
||||
if (!thrown_from && usr) //if something hasn't set it already (like a mech does when it launches)
|
||||
thrown_from = usr //then the user must have thrown it
|
||||
if (!istype(thrown_from, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas))
|
||||
playsound(src, throw_sound, 20, 1) //because mechs play the sound anyways
|
||||
var/turf/target = get_turf(A)
|
||||
var/atom/movable/adjtarget = new /atom/movable
|
||||
var/xadjust = 0
|
||||
var/yadjust = 0
|
||||
var/scaler = 0 //used to changed the normalised vector to the proper size
|
||||
scaler = throw_range / max(abs(target.x - src.x), abs(target.y - src.y)) //whichever is larger magnitude is what we normalise to
|
||||
if (target.x - src.x != 0) //just to avoid fucking with math for no reason
|
||||
xadjust = round((target.x - src.x) * scaler) //normalised vector is now scaled up to throw_range
|
||||
adjtarget.x = src.x + xadjust //the new target at max range
|
||||
else
|
||||
adjtarget.x = src.x
|
||||
if (target.y - src.y != 0)
|
||||
yadjust = round((target.y - src.y) * scaler)
|
||||
adjtarget.y = src.y + yadjust
|
||||
else
|
||||
adjtarget.y = src.y
|
||||
// log_admin("Adjusted target of [adjtarget.x] and [adjtarget.y], adjusted with [xadjust] and [yadjust] from [scaler]")
|
||||
..(get_turf(adjtarget), throw_range, throw_speed)
|
||||
thrown_from = null
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas/throw_impact(atom/hit_atom) //Pomf was right, I was wrong - Comic
|
||||
if(isliving(hit_atom) && hit_atom != usr) //if the target is a live creature other than the thrower
|
||||
var/mob/living/M = hit_atom
|
||||
if(ishuman(M)) //if they're a human species
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.m_intent == "run") //if they're set to run (though not necessarily running at that moment)
|
||||
if(prob(trip_prob)) //this probability is up for change and mostly a placeholder - Comic
|
||||
step(H, H.dir)
|
||||
H.visible_message("<span class='warning'>[H] was tripped by the bolas!</span>","<span class='warning'>Your legs have been tangled!</span>");
|
||||
H.Stun(2) //used instead of setting damage in vars to avoid non-human targets being affected
|
||||
H.Weaken(4)
|
||||
H.legcuffed = src //applies legcuff properties inherited through legcuffs
|
||||
src.loc = H
|
||||
H.update_inv_legcuffed()
|
||||
if(!H.legcuffed) //in case it didn't happen, we need a safety net
|
||||
throw_failed()
|
||||
else if(H.legcuffed) //if the target is already legcuffed (has to be walking)
|
||||
throw_failed()
|
||||
return
|
||||
else //walking, but uncuffed, or the running prob() failed
|
||||
H << "<span class='notice'>You stumble over the thrown bolas</span>"
|
||||
step(H, H.dir)
|
||||
H.Stun(1)
|
||||
throw_failed()
|
||||
return
|
||||
else
|
||||
M.Stun(2) //minor stun damage to anything not human
|
||||
throw_failed()
|
||||
return
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas/proc/throw_failed() //called when the throw doesn't entangle
|
||||
//log_admin("Logged as [thrown_from]")
|
||||
if(!thrown_from || !istype(thrown_from, /mob/living)) //in essence, if we don't know whether a person threw it
|
||||
qdel(src) //destroy it, to stop infinite bolases
|
||||
|
||||
/obj/item/weapon/legcuffs/bolas/Bump()
|
||||
..()
|
||||
throw_failed() //allows a mech bolas to be destroyed
|
||||
|
||||
/obj/item/weapon/holosign_creator
|
||||
name = "holographic sign projector"
|
||||
desc = "A handy-dandy hologaphic projector that displays a janitorial sign."
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
dat += "<A href='byond://?src=\ref[src];spell_choice=fleshtostone'>Flesh to Stone</A> (60)<BR>"
|
||||
dat += "<I>This spell will curse a person to immediately turn into an unmoving statue. The effect will eventually wear off if the statue is not destroyed.</I><BR>"
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];spell_choice=lightningbolt'>Lightning Bolt</A> (30)<BR>"
|
||||
dat += "<I>Charge up and throw lightning bolt at the nearby enemy. Classic. The longer you charge the more powerful the spell, beware of overcharge however!</I><BR>"
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];spell_choice=summonitem'>Instant Summons</A> (10)<BR>"
|
||||
dat += "<I>This spell can be used to bind a valuable item to you, bringing it to your hand at will. Using this spell while holding the bound item will allow you to unbind it. It does not require wizard garb.</I><BR>"
|
||||
|
||||
@@ -202,7 +205,7 @@
|
||||
uses--
|
||||
/*
|
||||
*/
|
||||
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment")
|
||||
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", lightningbolt = "Lightning Bolt", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment")
|
||||
var/already_knows = 0
|
||||
for(var/obj/effect/proc_holder/spell/wizard/aspell in H.spell_list)
|
||||
if(available_spells[href_list["spell_choice"]] == initial(aspell.name))
|
||||
@@ -305,6 +308,10 @@
|
||||
feedback_add_details("wizard_spell_learned","FS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/inflict_handler/flesh_to_stone(H)
|
||||
temp = "You have learned flesh to stone."
|
||||
if("lightningbolt")
|
||||
feedback_add_details("wizard_spell_learned","LB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/lightning(null)
|
||||
temp = "You have learned lightning bolt."
|
||||
if("summonitem")
|
||||
feedback_add_details("wizard_spell_learned","IS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/summonitem(null)
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/mind/target
|
||||
var/list/types = list("Owlman", "The Griffin")
|
||||
var/list/types = list()
|
||||
|
||||
/obj/machinery/wish_granter/New()
|
||||
for(var/supname in all_superheroes)
|
||||
types |= supname
|
||||
..()
|
||||
|
||||
/obj/machinery/wish_granter/attack_hand(var/mob/user as mob)
|
||||
usr.set_machine(src)
|
||||
|
||||
@@ -22,109 +28,18 @@
|
||||
else
|
||||
user << "The power of the Wish Granter have turned you into the superhero the station deserves. You are a masked vigilante, and answer to no man. Will you use your newfound strength to protect the innocent, or will you hunt the guilty?"
|
||||
|
||||
|
||||
var/wish
|
||||
if(types.len == 1)
|
||||
wish = pick(types)
|
||||
else
|
||||
wish = input("You want to become...","Wish") as null|anything in types
|
||||
if(!wish) return
|
||||
|
||||
var/mob/living/carbon/human/M = user
|
||||
switch(wish)
|
||||
if("Owlman")
|
||||
types -= "Owlman"
|
||||
M.fully_replace_character_name(M.real_name, "Owlman")
|
||||
|
||||
for(var/obj/item/W in M)
|
||||
M.unEquip(W)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/owl(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask(M), slot_wear_mask)
|
||||
|
||||
var/obj/item/weapon/card/id/syndicate/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card (Superhero)"
|
||||
W.access = get_all_accesses()
|
||||
W.assignment = "Superhero"
|
||||
W.registered_name = M.real_name
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
M.regenerate_icons()
|
||||
|
||||
var/datum/objective/protect/protect = new
|
||||
protect.owner = user.mind
|
||||
if(target)
|
||||
protect.target = target
|
||||
else
|
||||
protect.find_target()
|
||||
target = protect.target
|
||||
user.mind.objectives += protect
|
||||
|
||||
if("The Griffin")
|
||||
types -= "The Griffin"
|
||||
M.fully_replace_character_name(M.real_name, "The Griffin")
|
||||
|
||||
for(var/obj/item/W in M)
|
||||
M.unEquip(W)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/griffin(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/griffin(M), slot_head)
|
||||
|
||||
var/obj/item/weapon/card/id/syndicate/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card (Supervillain)"
|
||||
W.access = get_all_accesses()
|
||||
W.assignment = "Supervillain"
|
||||
W.registered_name = M.real_name
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
M.regenerate_icons()
|
||||
|
||||
var/datum/objective/assassinate/assasinate = new
|
||||
assasinate.owner = user.mind
|
||||
if(target)
|
||||
assasinate.target = target
|
||||
else
|
||||
assasinate.find_target()
|
||||
target = assasinate.target
|
||||
user.mind.objectives += assasinate
|
||||
|
||||
ticker.mode.traitors += user.mind
|
||||
user.mind.special_role = wish
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/OBJ in user.mind.objectives)
|
||||
user << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
|
||||
obj_count++
|
||||
|
||||
|
||||
//Time to hand out the powers, since they are currently generic
|
||||
if (!(HULK in user.mutations))
|
||||
user.dna.SetSEState(HULKBLOCK,1)
|
||||
|
||||
if (!(LASER in user.mutations))
|
||||
user.mutations.Add(LASER)
|
||||
|
||||
if (!(XRAY in user.mutations))
|
||||
user.mutations.Add(XRAY)
|
||||
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
user.see_in_dark = 8
|
||||
user.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if (!(RESIST_COLD in user.mutations))
|
||||
user.mutations.Add(RESIST_COLD)
|
||||
|
||||
if (!(RESIST_HEAT in user.mutations))
|
||||
user.mutations.Add(RESIST_HEAT)
|
||||
|
||||
if (!(TK in user.mutations))
|
||||
user.mutations.Add(TK)
|
||||
|
||||
if(!(REGEN in user.mutations))
|
||||
user.mutations.Add(REGEN)
|
||||
|
||||
user.update_mutations()
|
||||
var/datum/superheroes/S = all_superheroes[wish]
|
||||
if(S)
|
||||
S.create(M)
|
||||
|
||||
//Remove the wishgranter or teleport it randomly on the station
|
||||
if(!types.len)
|
||||
|
||||
@@ -468,3 +468,32 @@
|
||||
log_message("Launched a mouse-trap from [src.name], targeting [target]. HONK!")
|
||||
do_after_cooldown()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas
|
||||
name = "PCMK-6 Bolas Launcher"
|
||||
icon_state = "mecha_bolas"
|
||||
projectile = /obj/item/weapon/legcuffs/bolas
|
||||
fire_sound = 'sound/weapons/whip.ogg'
|
||||
projectiles = 10
|
||||
missile_speed = 1
|
||||
missile_range = 30
|
||||
projectile_energy_cost = 50
|
||||
equip_cooldown = 10
|
||||
|
||||
can_attach(obj/mecha/combat/gygax/M as obj)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
action(target)
|
||||
if(!action_checks(target)) return
|
||||
set_ready_state(0)
|
||||
var/obj/item/weapon/legcuffs/bolas/M = new projectile(chassis.loc)
|
||||
playsound(chassis, fire_sound, 50, 1)
|
||||
M.thrown_from = src
|
||||
M.throw_at(target, missile_range, missile_speed)
|
||||
projectiles--
|
||||
log_message("Fired from [src.name], targeting [target].")
|
||||
do_after_cooldown()
|
||||
return
|
||||
@@ -191,7 +191,7 @@
|
||||
"/obj/item/weapon/soap",
|
||||
"/obj/item/weapon/holosign_creator"
|
||||
)
|
||||
|
||||
|
||||
/obj/item/weapon/storage/belt/janitor/full/New()
|
||||
..()
|
||||
new /obj/item/device/lightreplacer(src)
|
||||
@@ -352,15 +352,15 @@
|
||||
origin_tech = "bluespace=4;syndicate=2"
|
||||
allow_quick_empty = 1
|
||||
can_hold = list()
|
||||
flags = NODROP
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/mask/gas/owl_mask(src)
|
||||
new /obj/item/clothing/under/owl(src)
|
||||
new /obj/item/weapon/grenade/smokebomb(src)
|
||||
new /obj/item/weapon/grenade/smokebomb(src)
|
||||
new /obj/item/device/detective_scanner(src)
|
||||
|
||||
|
||||
new /obj/item/weapon/grenade/smokebomb(src)
|
||||
new /obj/item/weapon/grenade/smokebomb(src)
|
||||
new /obj/item/weapon/legcuffs/bolas(src)
|
||||
new /obj/item/weapon/legcuffs/bolas(src)
|
||||
|
||||
// As a last resort, the belt can be used as a plastic explosive with a fixed timer (15 seconds). Naturally, you'll lose all your gear...
|
||||
// Of course, it could be worse. It could spawn a singularity!
|
||||
|
||||
@@ -49,6 +49,9 @@
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/greytide
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/weapon/storage/toolbox/electrical
|
||||
name = "electrical toolbox"
|
||||
icon_state = "yellow"
|
||||
|
||||
@@ -116,6 +116,7 @@ var/global/nologevent = 0
|
||||
<A href='?src=\ref[src];makerobot=\ref[M]'>Make Robot</A> |
|
||||
<A href='?src=\ref[src];makealien=\ref[M]'>Make Alien</A> |
|
||||
<A href='?src=\ref[src];makeslime=\ref[M]'>Make slime</A>
|
||||
<A href='?src=\ref[src];makesuper=\ref[M]'>Make Superhero</A>
|
||||
"}
|
||||
|
||||
//Simple Animals
|
||||
|
||||
@@ -516,6 +516,15 @@
|
||||
if(ticker.mode.xenos.len)
|
||||
dat += check_role_table("Xenos", ticker.mode.xenos, src)
|
||||
|
||||
if(ticker.mode.superheroes.len)
|
||||
dat += check_role_table("Superheroes", ticker.mode.superheroes, src)
|
||||
|
||||
if(ticker.mode.supervillains.len)
|
||||
dat += check_role_table("Supervillains", ticker.mode.supervillains, src)
|
||||
|
||||
if(ticker.mode.greyshirts.len)
|
||||
dat += check_role_table("Greyshirts", ticker.mode.greyshirts, src)
|
||||
|
||||
var/datum/game_mode/mutiny/mutiny = get_mutiny_mode()
|
||||
if(mutiny)
|
||||
dat += mutiny.check_antagonists_ui(src)
|
||||
|
||||
@@ -1397,6 +1397,16 @@
|
||||
|
||||
usr.client.cmd_admin_slimeize(H)
|
||||
|
||||
else if(href_list["makeslime"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makesuper"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be used on instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
usr.client.cmd_admin_super(H)
|
||||
|
||||
else if(href_list["makerobot"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
|
||||
@@ -281,6 +281,23 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/client/proc/cmd_admin_super(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make Superhero"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/type = input("Pick the Superhero","Superhero") as null|anything in all_superheroes
|
||||
var/datum/superheroes/S = all_superheroes[type]
|
||||
if(S)
|
||||
S.create(M)
|
||||
log_admin("[key_name(src)] has turned [M.key] into a Superhero.")
|
||||
message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into a Superhero.", 1)
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/*
|
||||
/client/proc/cmd_admin_monkeyize(var/mob/M in world)
|
||||
set category = "Event"
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
desc = "Woof!"
|
||||
icon_state = "corgihead"
|
||||
item_state = "chickensuit"
|
||||
flags = BLOCKHAIR
|
||||
flags = BLOCKHAIR | NODROP
|
||||
siemens_coefficient = 2.0
|
||||
|
||||
/obj/item/clothing/head/bearpelt
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
redcoat
|
||||
_color = "redcoat" //Exists for washing machines. Is not different from black shoes in any way.
|
||||
|
||||
/obj/item/clothing/shoes/black/greytide
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/clothing/shoes/brown
|
||||
name = "brown shoes"
|
||||
desc = "A pair of brown shoes."
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET
|
||||
flags_inv = HIDESHOES|HIDEJUMPSUIT
|
||||
siemens_coefficient = 2.0
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/clothing/suit/monkeysuit
|
||||
name = "Monkey Suit"
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
flags = ONESIZEFITSALL
|
||||
species_fit = list("Vox")
|
||||
|
||||
/obj/item/clothing/under/color/grey/greytide
|
||||
flags = ONESIZEFITSALL | NODROP
|
||||
|
||||
/obj/item/clothing/under/color/orange
|
||||
name = "orange jumpsuit"
|
||||
desc = "Don't wear this near paranoid security officers"
|
||||
|
||||
@@ -310,6 +310,20 @@ This function restores all organs.
|
||||
damage = damage*species.brute_mod
|
||||
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
|
||||
UpdateDamageIcon()
|
||||
if(LAssailant && ishuman(LAssailant))
|
||||
var/mob/living/carbon/human/H = LAssailant
|
||||
if(H.mind && H.mind in (ticker.mode.superheroes || ticker.mode.supervillains || ticker.mode.greyshirts))
|
||||
var/list/attack_bubble_recipients = list()
|
||||
var/mob/living/user
|
||||
for(var/mob/O in viewers(user, src))
|
||||
if (O.client && !( O.blinded ))
|
||||
attack_bubble_recipients.Add(O.client)
|
||||
spawn(0)
|
||||
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
|
||||
dmgIcon.pixel_x = (!lying) ? rand(-3,3) : rand(-11,12)
|
||||
dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1)
|
||||
//world << "x: [dmgIcon.pixel_x] AND y: [dmgIcon.pixel_y]"
|
||||
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
|
||||
receive_damage()
|
||||
if(BURN)
|
||||
damageoverlaytemp = 20
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/superheroes = list()
|
||||
var/list/datum/mind/supervillains = list()
|
||||
var/list/datum/mind/greyshirts = list()
|
||||
|
||||
/datum/superheroes
|
||||
var/name
|
||||
var/class
|
||||
var/list/default_genes = list(REGEN, NO_BREATH, RESIST_COLD)
|
||||
var/list/default_spells = list()
|
||||
|
||||
/datum/superheroes/proc/create(var/mob/living/carbon/human/H)
|
||||
assign_genes(H)
|
||||
assign_spells(H)
|
||||
equip(H)
|
||||
assign_id(H)
|
||||
|
||||
/datum/superheroes/proc/equip(var/mob/living/carbon/human/H)
|
||||
H.fully_replace_character_name(H.real_name, name)
|
||||
for(var/obj/item/W in H)
|
||||
if(istype(W,/obj/item/organ)) continue
|
||||
H.unEquip(W)
|
||||
|
||||
/datum/superheroes/proc/assign_genes(var/mob/living/carbon/human/H)
|
||||
if(default_genes.len)
|
||||
for(var/gene in default_genes)
|
||||
H.mutations |= gene
|
||||
H.update_mutations()
|
||||
|
||||
/datum/superheroes/proc/assign_spells(var/mob/living/carbon/human/H)
|
||||
if(default_spells.len)
|
||||
for(var/spell in default_spells)
|
||||
var/obj/effect/proc_holder/spell/wizard/S = spell
|
||||
if(!S) return
|
||||
H.spell_list += new S
|
||||
H.update_power_buttons()
|
||||
|
||||
/datum/superheroes/proc/assign_id(var/mob/living/carbon/human/H)
|
||||
var/obj/item/weapon/card/id/syndicate/W = new(H)
|
||||
W.registered_name = H.real_name
|
||||
W.access = get_all_accesses()
|
||||
if(class == "Superhero")
|
||||
W.name = "[H.real_name]'s ID Card (Superhero)"
|
||||
W.assignment = "Superhero"
|
||||
ticker.mode.superheroes += H.mind
|
||||
else if(class == "Supervillain")
|
||||
W.name = "[H.real_name]'s ID Card (Supervillain)"
|
||||
W.assignment = "Supervillain"
|
||||
ticker.mode.supervillains += H.mind
|
||||
|
||||
H.equip_to_slot_or_del(W, slot_wear_id)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/superheroes/owlman
|
||||
name = "Owlman"
|
||||
class = "Superhero"
|
||||
|
||||
/datum/superheroes/owlman/equip(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/owl(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask(H), slot_wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/bluespace/owlman(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(H), slot_glasses)
|
||||
|
||||
|
||||
/datum/superheroes/griffin
|
||||
name = "The Griffin"
|
||||
default_spells = list(/obj/effect/proc_holder/spell/wizard/targeted/recruit)
|
||||
class = "Supervillain"
|
||||
|
||||
/datum/superheroes/griffin/equip(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/griffin(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/griffin(H), slot_head)
|
||||
|
||||
|
||||
/datum/superheroes/lightnian
|
||||
name = "LightnIan"
|
||||
default_spells = list(/obj/effect/proc_holder/spell/wizard/targeted/lightning/lightnian)
|
||||
class = "Superhero"
|
||||
|
||||
/datum/superheroes/lightnian/equip(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/brown(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/corgisuit(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/corgi(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/bedsheet/orange(H), slot_back)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////POWERS/ABILITIES CODE/////////////////////////////////////////
|
||||
|
||||
|
||||
//The Griffin's special recruit abilitiy
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/recruit
|
||||
name = "Recruit Greyshirt"
|
||||
desc = "Allows you to recruit a conscious, non-braindead, non-catatonic human to be part of the Greyshirts, your personal henchmen. This works on Civilians only and you can recruit a maximum of 3!."
|
||||
panel = "Shadowling Abilities"
|
||||
charge_max = 450
|
||||
clothes_req = 0
|
||||
range = 1 //Adjacent to user
|
||||
var/recruiting = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/wizard/targeted/recruit/cast(list/targets)
|
||||
for(var/mob/living/carbon/human/target in targets)
|
||||
if(ticker.mode.greyshirts.len >= 3)
|
||||
usr << "<span class='warning'>You have already recruited the maximum number of henchmen.</span>"
|
||||
if(!in_range(usr, target))
|
||||
usr << "<span class='warning'>You need to be closer to enthrall [target].</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(!target.ckey)
|
||||
usr << "<span class='warning'>The target has no mind.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(target.stat)
|
||||
usr << "<span class='warning'>The target must be conscious.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(!ishuman(target))
|
||||
usr << "<span class='warning'>You can only recruit humans.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(target.mind.assigned_role != "Civilian")
|
||||
usr << "<span class='warning'>You can only recruit Civilians.</span>"
|
||||
if(recruiting)
|
||||
usr << "<span class='danger'>You are already recruiting!</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
recruiting = 1
|
||||
usr << "<span class='danger'>This target is valid. You begin the recruiting process.</span>"
|
||||
target << "<span class='userdanger'>[usr] focuses in concentration. Your head begins to ache.</span>"
|
||||
|
||||
for(var/progress = 0, progress <= 3, progress++)
|
||||
switch(progress)
|
||||
if(1)
|
||||
usr << "<span class='notice'>You begin by introducing yourself and explaining what you're about.</span>"
|
||||
usr.visible_message("<span class='danger'>[usr]'s introduces himself and explains his plans.</span>")
|
||||
if(2)
|
||||
usr << "<span class='notice'>You begin the recruitment of [target].</span>"
|
||||
usr.visible_message("<span class='danger'>[usr] leans over towards [target], whispering excitedly as he gives a speech.</span>")
|
||||
target << "<span class='danger'>You feel yourself agreeing with [usr], and a surge of loyalty begins building.</span>"
|
||||
target.Weaken(12)
|
||||
sleep(20)
|
||||
if(isloyal(target))
|
||||
usr << "<span class='notice'>They are enslaved by Nanotrasen. You feel their interest in your cause wane and disappear.</span>"
|
||||
usr.visible_message("<span class='danger'>[usr] stops talking for a moment, then moves back away from [target].</span>")
|
||||
target << "<span class='danger'>Your loyalty implant activates and a sharp pain reminds you of your loyalties to Nanotrasen.</span>"
|
||||
return
|
||||
if(3)
|
||||
usr << "<span class='notice'>You begin filling out the application form with [target].</span>"
|
||||
usr.visible_message("<span class='danger'>[usr] pulls out a pen and paper and begins filling an application form with [target].</span>")
|
||||
target << "<span class='danger'>You are being convinced by [usr] to fill out an application form to become a henchman.</span>" //Ow the edge
|
||||
if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a loyalty implant
|
||||
usr << "<span class='danger'>The enrollment process has been interrupted - you have lost the attention of [target].</span>"
|
||||
target << "<span class='warning'>You move away and are no longer under the charm of [usr]. The application form is null and void.</span>"
|
||||
recruiting = 0
|
||||
return
|
||||
|
||||
recruiting = 0
|
||||
usr << "<span class='notice'>You have recruited <b>[target]</b> as your henchman!</span>"
|
||||
target << "<span class='deadsay'><b>You have decided to enroll as a henchman for [usr]. You are now part of the feared 'Greyshirts'.</b></span>"
|
||||
target << "<span class='deadsay'><b>You must follow the orders of [usr], and help him succeed in his dastardly schemes.</span>"
|
||||
target << "<span class='deadsay'>You may not harm other Greyshirt or [usr]. However, you do not need to obey other Greyshirts.</span>"
|
||||
ticker.mode.greyshirts += target.mind
|
||||
target.set_species("Human")
|
||||
target.h_style = "Bald"
|
||||
target.fully_replace_character_name(target.real_name, "Generic Henchman ([rand(1, 1000)])")
|
||||
for(var/obj/item/W in target)
|
||||
if(istype(W,/obj/item/organ)) continue
|
||||
target.unEquip(W)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/greytide(target), slot_w_uniform)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(target), slot_shoes)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical/greytide(target), slot_l_hand)
|
||||
target.regenerate_icons()
|
||||
@@ -741,6 +741,17 @@
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_bolas
|
||||
name = "Exosuit Weapon Design (PCMK-6 Bolas Launcher)"
|
||||
desc = "Allows for the construction of PCMK-6 Bolas Launcher."
|
||||
id = "mech_bolas"
|
||||
build_type = MECHFAB
|
||||
req_tech = list("combat" = 3)
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas
|
||||
materials = list("$metal"=10000)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_teleporter
|
||||
name = "Exosuit Module (Teleporter Module)"
|
||||
desc = "An exosuit module that allows exosuits to teleport to any position in view."
|
||||
|
||||
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
|
After Width: | Height: | Size: 520 B |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 45 KiB |
@@ -167,6 +167,7 @@
|
||||
#include "code\datums\spells\horsemask.dm"
|
||||
#include "code\datums\spells\inflict_handler.dm"
|
||||
#include "code\datums\spells\knock.dm"
|
||||
#include "code\datums\spells\lightning.dm"
|
||||
#include "code\datums\spells\mind_transfer.dm"
|
||||
#include "code\datums\spells\projectile.dm"
|
||||
#include "code\datums\spells\summonitem.dm"
|
||||
@@ -1183,6 +1184,7 @@
|
||||
#include "code\modules\mob\living\carbon\life.dm"
|
||||
#include "code\modules\mob\living\carbon\shock.dm"
|
||||
#include "code\modules\mob\living\carbon\species.dm"
|
||||
#include "code\modules\mob\living\carbon\superheroes.dm"
|
||||
#include "code\modules\mob\living\carbon\alien\alien.dm"
|
||||
#include "code\modules\mob\living\carbon\alien\alien_defenses.dm"
|
||||
#include "code\modules\mob\living\carbon\alien\death.dm"
|
||||
|
||||