* Adds grues.
Adds swallow light spell.
Adds support to spell code for gradual-drain spells.
Adds racial spell spellmaster.

* Added sprites for grues.
Made a general /spell/racial path.

* Grues can now heal by consuming human meat.

* Removes unnecessary hulk underlay code.

* Adds a spell that allows grues to shatter lights.
/mob/living now has a var that holds a list of the tools that have been used to butcher it.
Autopsy scanners will now report what tools a human has been butchered with if the human's chest is scanned.
Being butchered by a grue, regardless of the tool used, will cause the autopsy scanner to report that the patient was eaten by a grue.

* Fixes conflicts.

* Puts map back to Boxstation.

* Addresses concerns.
This commit is contained in:
Shadowmech88
2016-12-20 18:45:45 -06:00
committed by Intigracy
parent 612b12d48d
commit eae088713c
24 changed files with 237 additions and 52 deletions

View File

@@ -1279,6 +1279,7 @@ var/default_colour_matrix = list(1,0,0,0,\
#define Sp_RECHARGE 1
#define Sp_CHARGES 2
#define Sp_HOLDVAR 4
#define Sp_GRADUAL 8
//spell range
#define SELFCAST -1
@@ -1359,6 +1360,7 @@ var/proccalls = 1
#define ORE_PROCESSING_ALLOY 2
//SOUND CHANNELS
#define CHANNEL_GRUE 1021 //only ever used to allow the ambient grue sound to be made to stop playing
#define CHANNEL_LOBBY 1022
#define CHANNEL_AMBIENCE 1023
#define CHANNEL_ADMINMUSIC 1024

View File

@@ -15,6 +15,7 @@
var/list/datum/autopsy_data_scanner/chemtraces = list()
var/target_name = null
var/timeofdeath = null
var/advanced_butchery = null
/datum/autopsy_data_scanner
var/weapon = null // this is the DEFINITE weapon type that was used
@@ -39,6 +40,23 @@
return W
/obj/item/weapon/autopsy_scanner/proc/add_data(var/datum/organ/external/O)
if(istype(O,/datum/organ/external/chest))
var/mob/living/carbon/human/H = O.owner
if(H)
if(H.advanced_butchery && H.advanced_butchery.len)
advanced_butchery = "\The [target_name] seems to have been butchered with"
for(var/i = 1, i <= H.advanced_butchery.len, i++)
var/tool_name = H.advanced_butchery[i]
if(tool_name == "grue")
advanced_butchery = "<span class='warning'>\The [target_name] is likely to have been eaten by a grue.</span>"
break
if(H.advanced_butchery.len == 1)
advanced_butchery += " \a [tool_name]."
else if(i != H.advanced_butchery.len)
advanced_butchery += " \a [tool_name][H.advanced_butchery.len > 2 ? "," : ""]"
else
advanced_butchery += " and \a [tool_name]."
if(!O.autopsy_data.len && !O.trace_chemicals.len)
return
@@ -77,6 +95,7 @@
if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V))
chemtraces += V
/obj/item/weapon/autopsy_scanner/verb/print_data()
set category = "Object"
set src in view(usr, 1)
@@ -154,6 +173,8 @@
scan_data += chemID
scan_data += "<br>"
scan_data += "<br>[advanced_butchery]<br>"
for(var/mob/O in viewers(usr))
O.show_message("<span class='warning'>\the [src] rattles and prints out a sheet of paper.</span>", 1)

View File

@@ -31,6 +31,8 @@
#define ishorrorform(A) (ishuman(A) && A.species && istype(A.species, /datum/species/horror))
#define isgrue(A) (ishuman(A) && A.species && istype(A.species, /datum/species/grue))
#define isbrain(A) istype(A, /mob/living/carbon/brain)
#define isalien(A) istype(A, /mob/living/carbon/alien)

View File

@@ -33,13 +33,13 @@
return
return ..()
/obj/screen/movable/spell_master/MouseEntered(location,control,params)
/obj/screen/movable/spell_master/MouseEntered(location,control,params)
openToolTip(usr,src,params,title = name,content = "Click and drag while closed to move this around the screen")
/obj/screen/movable/spell_master/MouseExited()
closeToolTip(usr)
/obj/screen/movable/spell_master/Click()
if(!spell_objects.len)
returnToPool(src)
@@ -159,14 +159,23 @@
screen_loc = ui_alien_master
length = 9
/obj/screen/movable/spell_master/malf
name = "Malfunction Modules"
icon_state = "grey_spell_ready"
open_state = "malf_open"
closed_state = "malf_closed"
screen_loc = ui_alien_master
/obj/screen/movable/spell_master/racial
name = "Racial Abilities"
icon_state = "racial_spell_ready"
open_state = "genetics_open"
closed_state = "genetics_closed"
screen_loc = ui_alien_master
//////////////ACTUAL SPELLS//////////////
@@ -184,7 +193,7 @@
var/icon/last_charged_icon
var/channeling_image
/obj/screen/spell/MouseEntered(location,control,params)
if(!spell)
return
@@ -205,10 +214,10 @@
if(SELFCAST)
dat += "<br>Range: Self"
openToolTip(usr,src,params,title = name,content = dat)
/obj/screen/spell/MouseExited()
closeToolTip(usr)
/obj/screen/spell/Destroy()
..()
spell = null
@@ -232,7 +241,7 @@
overlays -= spell.hud_state
if((spell.charge_type & Sp_RECHARGE) || (spell.charge_type & Sp_CHARGES))
if((spell.charge_type & Sp_RECHARGE) || (spell.charge_type & Sp_CHARGES) || (spell.charge_type & Sp_GRADUAL))
if(spell.charge_counter < spell.charge_max)
icon_state = "[spell_base]_spell_base"
if(spell.charge_counter > 0)

View File

@@ -28,14 +28,6 @@ Obviously, requires DNA2.
..()
block = HULKBLOCK
/datum/dna/gene/basic/grant_spell/hulk/OnDrawUnderlays(var/mob/M,var/g,var/fat)
if(M_HULK in M.mutations)
if(fat)
return "hulk_[fat]_s"
else
return "hulk_[g]_s"
return 0
/datum/dna/gene/basic/grant_spell/hulk/OnMobLife(var/mob/living/carbon/human/M)
if(!istype(M))
return

View File

@@ -5,7 +5,8 @@
voice_name = "unknown"
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
can_butcher = 0
can_butcher = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
var/list/hud_list[9]
var/datum/species/species //Contains icon generation and language information, set during New().
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
@@ -68,6 +69,10 @@
gender = NEUTER
meat_type = /obj/item/weapon/ore/diamond
/mob/living/carbon/human/grue/New(var/new_loc, delay_ready_dna = 0)
h_style = "Bald"
..(new_loc, "Grue")
/mob/living/carbon/human/frankenstein/New(var/new_loc, delay_ready_dna = 0) //Just fuck my shit up: the mob
f_style = pick(facial_hair_styles_list)
h_style = pick(hair_styles_list)
@@ -115,6 +120,8 @@
else
src.set_species()
movement_speed_modifier = species.move_speed_multiplier
default_language = get_default_language()
create_reagents(1000)
@@ -180,6 +187,8 @@
to_chat(src, "<b>You must eat to survive. Starvation for extended periods of time will kill you!</b>")
to_chat(src, "<b>Keep an eye out on the hunger indicator on the right of your screen; it will start flashing red and black when you're close to starvation.</b>")
update_colour(0,1)
/mob/living/carbon/human/player_panel_controls()
var/html=""
@@ -1326,6 +1335,9 @@
//if(src.species.language) src.remove_language(species.language)
if(src.species.abilities)
src.verbs -= species.abilities
if(species.spells)
for(var/spell in species.spells)
remove_spell(spell)
for(var/L in species.known_languages)
remove_language(L)
species.clear_organs(src)
@@ -1340,9 +1352,10 @@
if(species.default_language)
add_language(species.default_language)
if(src.species.abilities)
//if(src.species.language) src.add_language(species.language)
if(src.species.abilities)
src.verbs |= species.abilities
src.verbs |= species.abilities
if(species.spells)
for(var/spell in species.spells)
add_spell(spell, "racial_spell_ready", /obj/screen/movable/spell_master/racial)
if(force_organs || !src.organs || !src.organs.len)
src.species.create_organs(src)
var/datum/organ/internal/eyes/E = src.internal_organs_by_name["eyes"]

View File

@@ -189,7 +189,7 @@ var/global/list/damage_icon_parts = list()
var/husk = (M_HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/fat = (M_FAT in src.mutations) && (species && species.flags & CAN_BE_FAT)
var/hulk = (M_HULK in src.mutations) && !ishorrorform(src) // Part of the species.
var/hulk = (M_HULK in src.mutations) && !ishorrorform(src) && !isgrue(src) && mind.special_role != HIGHLANDER // Part of the species.
var/skeleton = (SKELETON in src.mutations)
var/g = "m"
@@ -353,31 +353,9 @@ var/global/list/damage_icon_parts = list()
O.underlays.len = 0
var/add_image = 0
var/g = "m"
if(gender == FEMALE)
g = "f"
// DNA2 - Drawing underlays.
var/hulk = 0
for(var/gene_type in active_genes)
var/datum/dna/gene/gene = dna_genes[gene_type]
if(!gene.block)
continue
if(gene.name == "Hulk")
hulk = 1
var/underlay=gene.OnDrawUnderlays(src,g,fat)
if(underlay)
//standing.underlays += underlay
O.underlays += underlay
add_image = 1
for(var/mut in mutations)
switch(mut)
if(M_HULK)
if(!hulk)
if(fat)
standing.underlays += "hulk_[fat]_s"
else
standing.underlays += "hulk_[g]_s"
add_image = 1
/*if(M_RESIST_COLD)
standing.underlays += "fire[fat]_s"
add_image = 1

View File

@@ -0,0 +1,59 @@
//For spells designed to be inherent abilities given to mobs via their species datum
/spell/swallow_light //Grue
name = "Swallow Light"
abbreviation = "SL"
desc = "Create a void of darkness around yourself."
panel = "Racial Abilities"
override_base = "racial"
hud_state = "racial_dark"
spell_flags = INCLUDEUSER
charge_type = Sp_GRADUAL
charge_max = 600
minimum_charge = 100
range = SELFCAST
cast_sound = 'sound/misc/grue_growl.ogg'
still_recharging_msg = "<span class='notice'>You're still regaining your strength.</span>"
/spell/swallow_light/cast(list/targets, mob/user)
user.set_light(8,-20)
playsound(user, cast_sound, 50, 1)
playsound(user, 'sound/misc/grue_ambience.ogg', 50, channel = CHANNEL_GRUE)
/spell/swallow_light/stop_casting(list/targets, mob/user)
user.set_light(0)
playsound(user, null, 50, channel = CHANNEL_GRUE)
/spell/swallow_light/choose_targets(mob/user = usr)
var/list/targets = list()
targets += user
return targets
/spell/swallow_light/is_valid_target(var/target, mob/user, options)
return(target == user)
/spell/shatter_lights //Grue
name = "Shatter Lights"
abbreviation = "ST"
desc = "Shatter all nearby lights with a shriek."
panel = "Racial Abilities"
override_base = "racial"
hud_state = "blackout"
charge_max = 1200
spell_flags = null
range = SELFCAST
cast_sound = 'sound/misc/grue_screech.ogg'
still_recharging_msg = "<span class='notice'>You're still regaining your strength.</span>"
/spell/shatter_lights/cast(list/targets, mob/user)
playsound(user, cast_sound, 100)
for(var/obj/machinery/light/L in range(7))
L.broken()
/spell/shatter_lights/choose_targets(mob/user = usr)
var/list/targets = list()
targets += user
return targets
/spell/shatter_lights/is_valid_target(var/target, mob/user, options)
return(target == user)

View File

@@ -93,6 +93,7 @@ var/global/list/whitelisted_species = list("Human")
var/chem_flags = 0 //how we handle chemicals and eating/drinking i guess
var/list/abilities = list() // For species-derived or admin-given powers
var/list/spells = list() // Because spells are the hip new thing to replace verbs
var/blood_color = DEFAULT_BLOOD //Red.
var/flesh_color = "#FFC896" //Pink.
@@ -132,6 +133,7 @@ var/global/list/whitelisted_species = list("Human")
var/move_speed_mod = 0 //Higher value is slower, lower is faster.
var/can_be_hypothermic = 1
var/has_sweat_glands = 1
var/move_speed_multiplier = 1 //This is a multiplier, and can make the mob either faster or slower.
/datum/species/New()
..()
@@ -883,3 +885,34 @@ var/global/list/whitelisted_species = list("Human")
qdel(src)
else
to_chat(user, "<span class='warning'>The used extract doesn't have any effect on \the [src].</span>")
/datum/species/grue
name = "Grue"
icobase = 'icons/mob/human_races/r_grue.dmi' // Normal icon set.
deform = 'icons/mob/human_races/r_def_grue.dmi' // Mutated icon set.
eyes = "grue_eyes_s"
attack_verb = "claws"
flags = HAS_LIPS | NO_PAIN | IS_WHITELISTED
punch_damage = 7
darksight = 8
default_mutations=list(M_HULK,M_CLAWS,M_TALONS)
burn_mod = 2
brute_mod = 2
move_speed_multiplier = 2
can_be_hypothermic = 0
has_mutant_race = 0
spells = list(/spell/swallow_light,/spell/shatter_lights)
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes/grue
)
/datum/species/grue/makeName()
return "grue"

View File

@@ -1305,11 +1305,14 @@ Thanks.
var/obj/item/tool = null //The tool that is used for butchering
var/speed_mod = 1.0 //The higher it is, the faster you butcher
var/butchering_time = 20 * size //2 seconds for tiny animals, 4 for small ones, 6 for normal sized ones (+ humans), 8 for big guys and 10 for biggest guys
var/tool_name = null
if(ishuman(user))
var/mob/living/carbon/human/H = user
tool = H.get_active_hand()
if(tool)
tool_name = tool.name
if(tool)
speed_mod = tool.is_sharp()
if(!speed_mod)
@@ -1318,16 +1321,27 @@ Thanks.
else
speed_mod = 0.0
if(M_CLAWS in H.mutations)
if(!istype(H.gloves))
speed_mod += 0.25
if(M_BEAK in H.mutations)
if(istype(H.wear_mask))
var/obj/item/clothing/mask/M = H.wear_mask
if(!(M.body_parts_covered & MOUTH)) //If our mask doesn't cover mouth, we can use our beak to help us while butchering
speed_mod += 0.25
if(!tool_name)
tool_name = "beak"
else
speed_mod += 0.25
if(!tool_name)
tool_name = "beak"
if(M_CLAWS in H.mutations)
if(!istype(H.gloves))
speed_mod += 0.25
if(!tool_name)
tool_name = "claws"
if(isgrue(H))
tool_name = "grue"
speed_mod += 0.5
else
speed_mod = 0.5
@@ -1381,6 +1395,10 @@ Thanks.
src.drop_meat(get_turf(src))
src.meat_taken++
src.being_butchered = 0
if(tool_name)
if(!advanced_butchery)
advanced_butchery = new()
advanced_butchery.Add(tool_name)
if(src.meat_taken < src.meat_amount)
to_chat(user, "<span class='info'>You cut a chunk of meat out of \the [src].</span>")

View File

@@ -71,6 +71,8 @@
var/obj/screen/schematics_background
var/shown_schematics_background = 0
var/list/advanced_butchery //Includes a list of the tools used to butcher the mob, detectable via autopsy scanner rather than examine.
/mob/living/proc/unsubLife(datum/sub)
while("\ref[sub]" in callOnLife)
callOnLife -= "\ref[sub]"

View File

@@ -257,6 +257,8 @@ var/global/obj/screen/fuckstat/FUCK = new
if(flags & HEAR_ALWAYS)
getFromPool(/mob/virtualhearer, src)
update_colour(0,1)
/mob/Del()
if(flags & HEAR_ALWAYS)
for(var/mob/virtualhearer/VH in virtualhearers)
@@ -1420,7 +1422,7 @@ var/list/slot_equipment_priority = list( \
statpanel(S.panel,"Required [S.holder_var_type]: [S.holder_var_amount]",S.connected_button)
else if(charge_type & Sp_CHARGES)
statpanel(S.panel,"[S.charge_max? "[S.charge_counter]/[S.charge_max] charges" : "Free"]",S.connected_button)
else if(charge_type & Sp_RECHARGE)
else if(charge_type & Sp_RECHARGE || charge_type & Sp_GRADUAL)
statpanel(S.panel,"[S.charge_max? "[S.charge_counter/10.0]/[S.charge_max/10] seconds" : "Free"]",S.connected_button)
sleep(world.tick_lag * 2)

View File

@@ -41,6 +41,15 @@
0,0.0,0.0,1,)
removed_type = /obj/item/organ/eyes/vox
/datum/organ/internal/eyes/grue
name = "monstrous eyes"
see_in_dark=8
colourmatrix = list(-1, 0, 0,
0,-1, 0,
0, 0,-1,
1, 1, 1)
removed_type = /obj/item/organ/eyes/grue
///////////////
// BIONIC EYES
///////////////

View File

@@ -172,6 +172,12 @@
prosthetic_name = "vox visual prosthesis"
organ_type = /datum/organ/internal/eyes/vox
/obj/item/organ/eyes/grue
name = "grue eyeballs"
// icon_state = "eyes"
prosthetic_name = "grue visual prosthesis"
organ_type = /datum/organ/internal/eyes/grue
/obj/item/organ/eyes/adv_1
name = "advanced prosthesis eyeballs"
robotic = 2

View File

@@ -37,6 +37,18 @@
var/subjectname = ""
var/subjectjob = null
/obj/item/weapon/reagent_containers/food/snacks/meat/human/after_consume(var/mob/user, var/datum/reagents/reagentreference)
if(!user)
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(isgrue(H))
H.adjustOxyLoss(-50)
H.heal_organ_damage(50, 0)
H.heal_organ_damage(0, 50)
H.adjustToxLoss(-50)
..()
/obj/item/weapon/reagent_containers/food/snacks/meat/rawchicken
name = "chicken meat"
desc = "This better be delicious."

View File

@@ -10,10 +10,11 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit?
var/charge_type = Sp_RECHARGE //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that
var/charge_type = Sp_RECHARGE //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that; can ALSO be made to gradually drain the charge with Sp_GRADUAL
var/charge_max = 100 //recharge time in deciseconds if charge_type = Sp_RECHARGE or starting charges if charge_type = Sp_CHARGES
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = Sp_RECHARGE or -- each cast if charge_type = Sp_CHARGES
var/minimum_charge = 0 //if set, the minimum charge_counter necessary to cast Sp_GRADUAL spells
var/still_recharging_msg = "<span class='notice'>The spell is still recharging.</span>"
var/silenced = 0 //not a binary (though it seems that it is at the moment) - the length of time we can't cast this for, set by the spell_master silence_spells()
@@ -84,6 +85,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
var/obj/screen/spell/connected_button
var/currently_channeled = 0
var/gradual_casting = FALSE //equals TRUE while a Sp_GRADUAL spell is actively being cast
///////////////////////
///SETUP AND PROCESS///
@@ -98,7 +100,15 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
/spell/proc/process()
spawn while(charge_counter < charge_max)
if(holder && !holder.timestopped)
charge_counter++
if(gradual_casting)
if(charge_counter <= 0)
charge_counter = 0
gradual_casting = FALSE
stop_casting(null, holder)
else
charge_counter--
else
charge_counter++
sleep(1)
return
@@ -128,6 +138,11 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
if(!targets && (spell_flags & WAIT_FOR_CLICK))
channel_spell(user, skipcharge)
return
if(cast_check(1, user))
if(gradual_casting)
gradual_casting = FALSE
stop_casting(targets, user)
return
if(!cast_check(skipcharge, user))
return
if(cast_delay && !spell_do_after(user, cast_delay))
@@ -221,6 +236,9 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
/spell/proc/cast(list/targets, mob/user) //the actual meat of the spell
return
/spell/proc/stop_casting(list/targets, mob/user)
return
/spell/proc/critfail(list/targets, mob/user) //the wizman has fucked up somehow
return
@@ -380,6 +398,10 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
if(user.vars[holder_var_type] < holder_var_amount)
to_chat(user, holder_var_recharging_msg())
return 0
if(charge_type & Sp_GRADUAL)
if(charge_counter < minimum_charge)
to_chat(user, still_recharging_msg)
return 0
return 1
/spell/proc/holder_var_recharging_msg()
@@ -399,6 +421,10 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
adjust_var(special_var_holder, holder_var_type, holder_var_amount)
else
adjust_var(user, holder_var_type, holder_var_amount)
if(charge_type & Sp_GRADUAL)
gradual_casting = TRUE
charge_counter -= 1
process()
/spell/proc/invocation(mob/user = usr, var/list/targets) //spelling the spell out and setting it on recharge/reducing charges amount

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

BIN
sound/misc/grue_growl.ogg Normal file

Binary file not shown.

BIN
sound/misc/grue_screech.ogg Normal file

Binary file not shown.

View File

@@ -1316,6 +1316,7 @@
#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\internals.dm"
#include "code\modules\mob\living\carbon\inventory.dm"
#include "code\modules\mob\living\carbon\racial_spells.dm"
#include "code\modules\mob\living\carbon\shock.dm"
#include "code\modules\mob\living\carbon\species.dm"
#include "code\modules\mob\living\carbon\stripping.dm"