|
| 1 | +#define DISCHARGE_LOSS 100 //how much power is lost during a discharge |
| 2 | + |
1 | 3 | /datum/species/ethereal |
2 | 4 | name = "Ethereal" |
3 | 5 | id = "ethereal" |
|
46 | 48 | var/emageffect = FALSE |
47 | 49 | var/emag_timer = null |
48 | 50 | var/emag_speed = 4 //how many deciseconds between each colour cycle |
| 51 | + var/discharging = FALSE |
| 52 | + |
49 | 53 | var/r1 |
50 | 54 | var/g1 |
51 | 55 | var/b1 |
|
58 | 62 |
|
59 | 63 | var/obj/effect/dummy/lighting_obj/moblight/species/ethereal_light |
60 | 64 |
|
| 65 | +//////////////////////////////////////////////////////////////////////////////////// |
| 66 | +//---------------------------------Extra Stuff------------------------------------// |
| 67 | +//////////////////////////////////////////////////////////////////////////////////// |
| 68 | +/datum/species/ethereal/random_name(gender,unique,lastname) |
| 69 | + if(unique) |
| 70 | + return random_unique_ethereal_name() |
| 71 | + |
| 72 | + var/randname = ethereal_name() |
| 73 | + |
| 74 | + return randname |
| 75 | + |
61 | 76 | /datum/species/ethereal/Destroy(force) |
62 | 77 | QDEL_NULL(ethereal_light) |
63 | 78 | return ..() |
64 | 79 |
|
| 80 | +//////////////////////////////////////////////////////////////////////////////////// |
| 81 | +//----------------------------Species Gain and Loss-------------------------------// |
| 82 | +//////////////////////////////////////////////////////////////////////////////////// |
65 | 83 | /datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) |
66 | 84 | . = ..() |
67 | 85 | if(!ishuman(C)) |
|
89 | 107 | deltimer(emag_timer) |
90 | 108 | return ..() |
91 | 109 |
|
92 | | -/datum/species/ethereal/random_name(gender,unique,lastname) |
93 | | - if(unique) |
94 | | - return random_unique_ethereal_name() |
95 | | - |
96 | | - var/randname = ethereal_name() |
97 | | - |
98 | | - return randname |
99 | | - |
100 | | -/datum/species/ethereal/proc/setup_color(mob/living/carbon/human/ethereal) |
101 | | - default_color = ethereal.dna.features["mcolor"] |
102 | | - r1 = GETREDPART(default_color) |
103 | | - g1 = GETGREENPART(default_color) |
104 | | - b1 = GETBLUEPART(default_color) |
105 | | - var/list/hsl = rgb2hsl(r1, g1, b1) |
106 | | - //both saturation and lightness are a scale of 0 to 1 |
107 | | - hsl[2] = min(hsl[2], 0.7) //don't let saturation be too high or it's overwhelming |
108 | | - hsl[3] = max(hsl[3], 0.5) //don't let lightness be too low or it looks like a void of light |
109 | | - var/list/rgb = hsl2rgb(hsl[1], hsl[2], hsl[3]) //terrible way to do it, but it works |
110 | | - r1 = rgb[1] |
111 | | - g1 = rgb[2] |
112 | | - b1 = rgb[3] |
113 | | - |
| 110 | +//////////////////////////////////////////////////////////////////////////////////// |
| 111 | +//---------------------------------Light Handler----------------------------------// |
| 112 | +//////////////////////////////////////////////////////////////////////////////////// |
114 | 113 | /datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/ethereal) |
115 | 114 | . = ..() |
116 | 115 | if(!ethereal_light) |
|
137 | 136 | fixed_mut_color = rgb(128,128,128) |
138 | 137 | ethereal.update_body() |
139 | 138 |
|
140 | | -/// Special handling for getting hit with a light eater |
| 139 | +//////////////////////////////////////////////////////////////////////////////////// |
| 140 | +//------------------------------Light Colour Helper-------------------------------// |
| 141 | +//////////////////////////////////////////////////////////////////////////////////// |
| 142 | +/datum/species/ethereal/proc/setup_color(mob/living/carbon/human/ethereal) |
| 143 | + default_color = ethereal.dna.features["mcolor"] |
| 144 | + r1 = GETREDPART(default_color) |
| 145 | + g1 = GETGREENPART(default_color) |
| 146 | + b1 = GETBLUEPART(default_color) |
| 147 | + var/list/hsl = rgb2hsl(r1, g1, b1) |
| 148 | + //both saturation and lightness are a scale of 0 to 1 |
| 149 | + hsl[2] = min(hsl[2], 0.7) //don't let saturation be too high or it's overwhelming |
| 150 | + hsl[3] = max(hsl[3], 0.5) //don't let lightness be too low or it looks like a void of light |
| 151 | + var/list/rgb = hsl2rgb(hsl[1], hsl[2], hsl[3]) //terrible way to do it, but it works |
| 152 | + r1 = rgb[1] |
| 153 | + g1 = rgb[2] |
| 154 | + b1 = rgb[3] |
| 155 | + |
| 156 | +//////////////////////////////////////////////////////////////////////////////////// |
| 157 | +//------------------------------------Light eater---------------------------------// |
| 158 | +//////////////////////////////////////////////////////////////////////////////////// |
141 | 159 | /datum/species/ethereal/proc/on_light_eater(mob/living/carbon/human/source, datum/light_eater) |
142 | 160 | SIGNAL_HANDLER |
143 | 161 | spec_emp_act(source, EMP_LIGHT) |
144 | 162 | return COMPONENT_BLOCK_LIGHT_EATER |
145 | 163 |
|
| 164 | +//////////////////////////////////////////////////////////////////////////////////// |
| 165 | +//------------------------------------EMP effects---------------------------------// |
| 166 | +//////////////////////////////////////////////////////////////////////////////////// |
146 | 167 | /datum/species/ethereal/spec_emp_act(mob/living/carbon/human/H, severity) |
147 | 168 | .=..() |
148 | 169 | if(!EMPeffect) |
|
156 | 177 | spec_updatehealth(H) |
157 | 178 | to_chat(H, span_notice("You feel more energized as your shine comes back.")) |
158 | 179 |
|
| 180 | +//////////////////////////////////////////////////////////////////////////////////// |
| 181 | +//-----------------------------------Emag effects---------------------------------// |
| 182 | +//////////////////////////////////////////////////////////////////////////////////// |
159 | 183 | /datum/species/ethereal/spec_emag_act(mob/living/carbon/human/H, mob/user, obj/item/card/emag/emag_card) |
160 | 184 | if(emageffect) |
161 | 185 | return FALSE |
|
188 | 212 | animate(H, emag_speed, color = null) //back to boring |
189 | 213 | H.visible_message(span_danger("[H]'s light goes back to it's normal state!")) |
190 | 214 |
|
| 215 | +//////////////////////////////////////////////////////////////////////////////////// |
| 216 | +//-------------------------------Discharge effect---------------------------------// |
| 217 | +//////////////////////////////////////////////////////////////////////////////////// |
| 218 | +/datum/species/ethereal/proc/discharge_process(mob/living/carbon/human/H) |
| 219 | + H.visible_message(span_danger("[H] begins to spark violently!"), span_warning("You begin to lose control over your energy!")) |
| 220 | + |
| 221 | + var/static/mutable_appearance/overcharge //shameless copycode from lightning spell copied from another codebase copied from another codebase |
| 222 | + overcharge = overcharge || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER) |
| 223 | + H.add_overlay(overcharge) |
| 224 | + |
| 225 | + discharging = TRUE |
| 226 | + if(!do_after(H, 5 SECONDS, timed_action_flags = IGNORE_ALL)) |
| 227 | + discharging = FALSE |
| 228 | + stack_trace("[H]'s Ethereal discharge was canceled somehow.") |
| 229 | + return //nothing should be able to stop this do_after, but just in case |
| 230 | + discharging = FALSE |
| 231 | + |
| 232 | + H.cut_overlay(overcharge) |
| 233 | + |
| 234 | + if(H.nutrition > NUTRITION_LEVEL_FULL) |
| 235 | + H.visible_message(span_notice("[H] stops sparking."), span_notice("Your energy settles down again.")) |
| 236 | + return //if they successfully release into an apc, no more discharge |
| 237 | + |
| 238 | + H.flash_lighting_fx(5, 7, current_color) |
| 239 | + playsound(H, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) |
| 240 | + H.visible_message(span_danger("[H] violently discharges energy!"), span_warning("You violently discharge energy!")) |
| 241 | + |
| 242 | + H.adjust_nutrition(-DISCHARGE_LOSS) |
| 243 | + tesla_zap(H, 2, H.nutrition * 5, TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_ALLOW_DUPLICATES) |
| 244 | + H.electrocute_act(0, "discharge bolt", override = TRUE, stun = TRUE) |
| 245 | + |
| 246 | +//////////////////////////////////////////////////////////////////////////////////// |
| 247 | +//----------------------------External Charging effects---------------------------// |
| 248 | +//////////////////////////////////////////////////////////////////////////////////// |
191 | 249 | /datum/species/ethereal/spec_rad_act(mob/living/carbon/human/H, amount, collectable_radiation) |
192 | 250 | if(!collectable_radiation) |
193 | 251 | return |
|
205 | 263 | H.adjust_nutrition(P.damage * (1 - (H.getarmor(null, RAD) / 100))) |
206 | 264 | return TRUE |
207 | 265 |
|
| 266 | +/datum/species/ethereal/on_hit(obj/projectile/P, mob/living/carbon/human/H) |
| 267 | + . = ..() |
| 268 | + if(P.armor_flag == ENERGY) |
| 269 | + H.adjust_nutrition(P.damage * (1 - (H.getarmor(null, ENERGY) / 100))) |
| 270 | + |
| 271 | +/datum/species/ethereal/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, zone = BODY_ZONE_R_ARM, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE) |
| 272 | + H.adjust_nutrition(shock_damage) //don't charge too much or discharge will create an infinite loop with it's self shock |
| 273 | + return |
| 274 | + |
| 275 | +//////////////////////////////////////////////////////////////////////////////////// |
| 276 | +//--------------------------------Hunger Handling---------------------------------// |
| 277 | +//////////////////////////////////////////////////////////////////////////////////// |
208 | 278 | /datum/species/ethereal/spec_life(mob/living/carbon/human/H) |
209 | 279 | .=..() |
210 | 280 | if(H.stat == DEAD) |
211 | 281 | return |
212 | | - if(H.nutrition > NUTRITION_LEVEL_FULL && prob(10))//10% each tick for ethereals to explosively release excess energy if it reaches dangerous levels |
| 282 | + |
| 283 | + if(H.nutrition < NUTRITION_LEVEL_ALMOST_FULL) //passive charging if in starlight |
| 284 | + var/starlight = FALSE |
| 285 | + if(istype(get_turf(H), /turf/open/space)) |
| 286 | + starlight = TRUE |
| 287 | + else |
| 288 | + for(var/turf/T in view(H, 2)) |
| 289 | + if(istype(T, /turf/open/space)) |
| 290 | + starlight = TRUE |
| 291 | + break |
| 292 | + |
| 293 | + if(starlight) |
| 294 | + H.adjust_nutrition(10) //small enough number so it doesn't jump from below almost full to being in discharge range |
| 295 | + |
| 296 | + if(!discharging && H.nutrition > NUTRITION_LEVEL_FULL && prob(10))//10% each tick for ethereals to explosively release excess energy if it reaches dangerous levels |
213 | 297 | discharge_process(H) |
214 | 298 | else if(H.nutrition < NUTRITION_LEVEL_STARVING && H.health > 10.5) |
215 | 299 | apply_damage(0.65, TOX, null, 0, H) |
|
230 | 314 | H.clear_alert("ethereal_charge") |
231 | 315 | H.clear_alert("ethereal_overcharge") |
232 | 316 |
|
233 | | -/datum/species/ethereal/proc/discharge_process(mob/living/carbon/human/H) |
234 | | - to_chat(H, "<span class='warning'>You begin to lose control over your charge!</span>") |
235 | | - H.visible_message("<span class='danger'>[H] begins to spark violently!</span>") |
236 | | - var/static/mutable_appearance/overcharge //shameless copycode from lightning spell copied from another codebase copied from another codebase |
237 | | - overcharge = overcharge || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER) |
238 | | - H.add_overlay(overcharge) |
239 | | - if(do_after(H, 5 SECONDS, timed_action_flags = IGNORE_ALL)) |
240 | | - H.flash_lighting_fx(5, 7, current_color) |
241 | | - playsound(H, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) |
242 | | - H.cut_overlay(overcharge) |
243 | | - tesla_zap(H, 2, H.nutrition * 5, TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_ALLOW_DUPLICATES) |
244 | | - H.nutrition = NUTRITION_LEVEL_MOSTLY_FULL |
245 | | - to_chat(H, "<span class='warning'>You violently discharge energy!</span>") |
246 | | - H.visible_message("<span class='danger'>[H] violently discharges energy!</span>") |
247 | | - H.electrocute_act(0, "discharge bolt", override = TRUE, stun = TRUE) |
248 | | - return |
249 | | - |
| 317 | +//////////////////////////////////////////////////////////////////////////////////// |
| 318 | +//----------------------------Species preference info-----------------------------// |
| 319 | +//////////////////////////////////////////////////////////////////////////////////// |
250 | 320 | /datum/species/ethereal/get_features() |
251 | 321 | var/list/features = ..() |
252 | 322 |
|
|
295 | 365 | list( |
296 | 366 | SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, |
297 | 367 | SPECIES_PERK_ICON = "bolt", |
298 | | - SPECIES_PERK_NAME = "Nuclear-Powered", |
299 | | - SPECIES_PERK_DESC = "Ethereals can gain charge when absorbing certain kinds of radiation.", |
| 368 | + SPECIES_PERK_NAME = "Energy-Sponge", |
| 369 | + SPECIES_PERK_DESC = "Ethereals can gain charge when absorbing certain kinds of energy or radiation.", |
300 | 370 | ), |
301 | 371 | list( |
302 | 372 | SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, |
|
307 | 377 | ) |
308 | 378 |
|
309 | 379 | return to_add |
| 380 | + |
| 381 | +#undef DISCHARGE_LOSS |
0 commit comments