Merge remote-tracking branch 'upstream/master' into too-many-monkeys-jumping-on-the-bed

This commit is contained in:
Coul
2019-09-15 10:46:27 -04:00
108 changed files with 2470 additions and 1312 deletions
+14 -3
View File
@@ -34,17 +34,28 @@ actual development.
* Pull requests should be atomic; Make one commit for each distinct change, so if a part
of a pull request needs to be removed/changed, you may simply modify that single commit.
Due to limitations of the engine, this may not always be possible; but do try your best.
* Document and explain your pull requests thoroughly. Detail what each commit changes,
and why it changes it. We do not want to have to read all of you commit names to figure
out what your pull request is about.
* Document and explain your pull requests thoroughly. Failure to do so will delay a PR as
we question why changes were made. This is especially important if you're porting a PR
from another codebase (i.e. TG) and divert from the original. Explaining with single
comment on why you've made changes will help us review the PR faster and understand your
decision making process.
* Any pull request must have a changelog, this is to allow us to know when a PR is deployed
on the live server. Inline changelogs are supported through the format described
[here](https://github.com/ParadiseSS13/Paradise/pull/3291#issuecomment-172950466)
and should be used rather than manually edited .yml file changelogs.
* Pull requests should not have any merge commits except in the case of fixing merge
conflicts for an existing pull request. New pull requests should not have any merge
commits. Use `git rebase` or `git reset` to update your branches, not `git pull`.
* Please explain why you are submitting the pull request, and how you think your change will be beneficial to the game. Failure to do so will be grounds for rejecting the PR.
* If your pull request is not finished make sure it is at least testable in a live environment. Pull requests that do not at least meet this requirement may be closed at maintainer discretion. You may request a maintainer reopen the pull request when you're ready, or make a new one.
* While we have no issue helping contributors (and especially new contributors) bring reasonably sized contributions up to standards via the pull request review process, larger contributions are expected to pass a higher bar of completeness and code quality *before* you open a pull request. Maintainers may close such pull requests that are deemed to be substantially flawed. You should take some time to discuss with maintainers or other contributors on how to improve the changes.
#### Using Changelog
* Tags used in changelog include add/rscadd, del/rscdel, fix/fixes, typo/spellcheck.
* Without specifying a name it will default to using your GitHub name.
+13 -6
View File
@@ -1,11 +1,16 @@
**What does this PR do:**
Include a small to medium description of what your PR changes. Feel free to give it a little flourish if you want to show off a new feature more completely.
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull request process. -->
**Images of sprite/map changes (IF APPLICABLE):**
If you did not make a map or sprite edit, you may leave this section blank. You may include a gif of your feature if you want
## What Does This PR Do
<!-- Include a small to medium description of what your PR changes. Document every changes or this may delay review or even discourage maintainers from merging your PR! -->
**Changelog:**
*Remove this line, and appropriate fields from the changelog*
## Why It's Good For The Game
<!-- Please add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
## Images of changes
<!-- If you did not make a map or sprite edit, you may delete this section. You may include a gif of your feature if you want -->
## Changelog
:cl:
add: Added new things
del: Removed old things
@@ -21,3 +26,5 @@ spellcheck: fixed a few typos
experiment: added an experimental thingy
/:cl:
<!-- Both :cl:'s are required for the changelog to work! You can put your name to the right of the first :cl: if you want to overwrite your GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. -->
+1 -1
View File
@@ -298,7 +298,7 @@ This is always put in the attack log.
loglevel = ATKLOG_FEW
else if(istype(user) && !user.ckey && !target.ckey) // Attacks between NPCs are only shown to admins with ATKLOG_ALL
loglevel = ATKLOG_ALL
else if(!user.ckey || !target.ckey) // Player v NPC combat is de-prioritized.
else if(!user.ckey || !target.ckey || (user.ckey == target.ckey)) // Player v NPC combat is de-prioritized. Also no self-harm, nobody cares
loglevel = ATKLOG_ALMOSTALL
else
var/area/A = get_area(target)
+5
View File
@@ -244,6 +244,9 @@
//cube monkey limit
var/cubemonkeycap = 20
// Makes gamemodes respect player limits
var/enable_gamemode_player_limit = 0
/datum/configuration/New()
for(var/T in subtypesof(/datum/game_mode))
@@ -723,6 +726,8 @@
config.developer_express_start = 1
if("disable_localhost_admin")
config.disable_localhost_admin = 1
if("enable_gamemode_player_limit")
config.enable_gamemode_player_limit = 1
else
log_config("Unknown setting in configuration: '[name]'")
+6 -6
View File
@@ -212,7 +212,7 @@
/datum/action/item_action/toggle_unfriendly_fire
name = "Toggle Friendly Fire \[ON\]"
desc = "Toggles if the staff causes friendly fire."
desc = "Toggles if the club's blasts cause friendly fire."
button_icon_state = "vortex_ff_on"
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
@@ -220,8 +220,8 @@
UpdateButtonIcon()
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon()
if(istype(target, /obj/item/hierophant_staff))
var/obj/item/hierophant_staff/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.friendly_fire_check)
button_icon_state = "vortex_ff_off"
name = "Toggle Friendly Fire \[OFF\]"
@@ -247,12 +247,12 @@
/datum/action/item_action/vortex_recall
name = "Vortex Recall"
desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.<br>If no such rune exists, will produce a rune at your location."
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
button_icon_state = "vortex_recall"
/datum/action/item_action/vortex_recall/IsAvailable()
if(istype(target, /obj/item/hierophant_staff))
var/obj/item/hierophant_staff/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.teleporting)
return 0
return ..()
+1 -1
View File
@@ -124,8 +124,8 @@ datum/map_template/ruin/lavaland/ash_walker
id = "hierophant"
description = "A strange, square chunk of metal of massive size. Inside awaits only death and many, many squares."
suffix = "lavaland_surface_hierophant.dmm"
allow_duplicates = FALSE
always_place = TRUE
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/blood_drunk_miner
name = "Blood-Drunk Miner"
+6 -6
View File
@@ -383,18 +383,18 @@
name = "Repulse"
desc = "This spell throws everything around the user away."
charge_max = 400
clothes_req = 1
clothes_req = TRUE
invocation = "GITTAH WEIGH"
invocation_type = "shout"
range = 5
cooldown_min = 150
selection_type = "view"
sound = 'sound/magic/repulse.ogg'
var/maxthrow = 5
var/sparkle_path = /obj/effect/temp_visual/gravpush
action_icon_state = "repulse"
sound = 'sound/magic/repulse.ogg'
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets, mob/user = usr)
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets, mob/user = usr, stun_amt = 2)
var/list/thrownatoms = list()
var/atom/throwtarget
var/distfromcaster
@@ -411,16 +411,16 @@
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
distfromcaster = get_dist(user, AM)
if(distfromcaster == 0)
if(istype(AM, /mob/living))
if(isliving(AM))
var/mob/living/M = AM
M.Weaken(5)
M.adjustBruteLoss(5)
to_chat(M, "<span class='userdanger'>You're slammed into the floor by a mystical force!</span>")
else
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
if(istype(AM, /mob/living))
if(isliving(AM))
var/mob/living/M = AM
M.Weaken(2)
M.Weaken(stun_amt)
to_chat(M, "<span class='userdanger'>You're thrown back by a mystical force!</span>")
spawn(0)
AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time.
+5 -14
View File
@@ -1037,7 +1037,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/explosives/grenadier
name = "Grenadier's belt"
desc = "A belt containing 25 lethally dangerous and destructive grenades."
desc = "A belt containing 26 lethally dangerous and destructive grenades."
item = /obj/item/storage/belt/grenade/full
cost = 30
surplus = 0
@@ -1052,15 +1052,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
gamemodes = list(/datum/game_mode/nuclear)
surplus = 35
/datum/uplink_item/explosives/saringrenades
name = "Sarin Gas Grenades"
desc = "A box of four (4) grenades filled with Sarin, a deadly neurotoxin. Use extreme caution when handling and be sure to vacate the premise after using; ensure communication is maintained with team to avoid accidental gassings."
reference = "TGG"
item = /obj/item/storage/box/syndie_kit/sarin
cost = 12
gamemodes = list(/datum/game_mode/nuclear)
surplus = 0
/datum/uplink_item/explosives/atmosn2ogrenades
name = "Knockout Gas Grenades"
desc = "A box of two (2) grenades that spread knockout gas over a large area. Equip internals before using one of these."
@@ -1651,10 +1642,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/bundles_TC/c20r
name = "C-20r Bundle"
desc = "Old Faithful: The classic C-20r, bundled with two magazines and a (surplus) suppressor at discount price."
desc = "Old Faithful: The classic C-20r, bundled with three magazines and a (surplus) suppressor at discount price."
reference = "C20B"
item = /obj/item/storage/backpack/duffel/syndie/c20rbundle
cost = 14 // normally 17
cost = 18 // normally 21
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/bundles_TC/cyber_implants
@@ -1669,10 +1660,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/bundles_TC/medical
name = "Medical Bundle"
desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \
a Donksoft LMG and a box of riot darts."
a medical beam gun and a pair of syndicate magboots."
reference = "MEDB"
item = /obj/item/storage/backpack/duffel/syndie/med/medicalbundle
cost = 15 // normally 20
cost = 20 // normally 24
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/bundles_TC/sniper
+2 -1
View File
@@ -104,6 +104,7 @@ var/list/blob_nodes = list()
to_chat(blob.current, "<b>Find a good location to spawn the core and then take control and overwhelm the station!</b>")
to_chat(blob.current, "<b>When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.</b>")
to_chat(blob.current, "<b>If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover.</b>")
SEND_SOUND(blob.current, 'sound/magic/mutate.ogg')
return
/datum/game_mode/blob/proc/show_message(var/message)
@@ -207,4 +208,4 @@ var/list/blob_nodes = list()
/datum/game_mode/proc/update_blob_icons_removed(datum/mind/mob_mind)
var/datum/atom_hud/antag/antaghud = huds[ANTAG_HUD_BLOB]
antaghud.leave_hud(mob_mind.current)
set_antag_hud(mob_mind.current, null)
set_antag_hud(mob_mind.current, null)
+1 -1
View File
@@ -50,7 +50,7 @@
if((player.client)&&(player.ready))
playerC++
if(playerC >= required_players)
if(!config.enable_gamemode_player_limit || (playerC >= required_players))
return 1
return 0
@@ -82,7 +82,6 @@
/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
DeactivateStealth()
return 0
/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
DeactivateStealth()
@@ -2,7 +2,6 @@
melee_damage_lower = 15
melee_damage_upper = 15
armour_penetration = 0
damage_transfer = 0.6
playstyle_string = "As an <b>Assassin</b> type you do medium damage and have no damage resistance, but can enter stealth, massively increasing the damage of your next attack and causing it to ignore armor. Stealth is broken when you attack or take damage."
magic_fluff_string = "..And draw the Space Ninja, a lethal, invisible assassin."
tech_fluff_string = "Boot sequence complete. Assassin modules loaded. Holoparasite swarm online."
+1 -1
View File
@@ -116,7 +116,7 @@
if(!drownee)
return
if(drownee && (drownee.lying || deep_water)) //Mob lying down or water is deep (determined by controller)
if(drownee && ((drownee.lying && !drownee.player_logged) || deep_water)) //Mob lying down and not SSD or water is deep (determined by controller)
if(drownee.internal)
return //Has internals, no drowning
if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations))
+177 -47
View File
@@ -121,9 +121,10 @@
product_records = list()
hidden_records = list()
coin_records = list()
build_inventory(products, product_records, start_empty = TRUE)
build_inventory(contraband, hidden_records, start_empty = TRUE)
build_inventory(premium, coin_records, start_empty = TRUE)
if(refill_canister)
build_inventory(products, product_records, start_empty = TRUE)
build_inventory(contraband, hidden_records, start_empty = TRUE)
build_inventory(premium, coin_records, start_empty = TRUE)
for(var/obj/item/vending_refill/VR in component_parts)
restock(VR)
@@ -1275,16 +1276,57 @@
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/cotton = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3,
/obj/item/seeds/cabbage = 3, /obj/item/seeds/carrot = 3, /obj/item/seeds/cherry = 3, /obj/item/seeds/chanter = 3,
/obj/item/seeds/chili = 3, /obj/item/seeds/cocoapod = 3, /obj/item/seeds/coffee = 3, /obj/item/seeds/comfrey =3, /obj/item/seeds/corn = 3,
/obj/item/seeds/nymph =3, /obj/item/seeds/eggplant = 3, /obj/item/seeds/grape = 3, /obj/item/seeds/grass = 3, /obj/item/seeds/lemon = 3,
/obj/item/seeds/lime = 3, /obj/item/seeds/onion = 3, /obj/item/seeds/orange = 3, /obj/item/seeds/peanuts = 3, /obj/item/seeds/pineapple = 3, /obj/item/seeds/potato = 3, /obj/item/seeds/poppy = 3,
/obj/item/seeds/pumpkin = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/wheat/rice = 3, /obj/item/seeds/soya = 3, /obj/item/seeds/sunflower = 3, /obj/item/seeds/sugarcane = 3,
/obj/item/seeds/tea = 3, /obj/item/seeds/tobacco = 3, /obj/item/seeds/tomato = 3,
/obj/item/seeds/tower = 3, /obj/item/seeds/watermelon = 3, /obj/item/seeds/wheat = 3, /obj/item/seeds/whitebeet = 3)
contraband = list(/obj/item/seeds/amanita = 2, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/liberty = 2, /obj/item/seeds/nettle = 2,
/obj/item/seeds/plump = 2, /obj/item/seeds/reishi = 2, /obj/item/seeds/cannabis = 3, /obj/item/seeds/starthistle = 2, /obj/item/seeds/fungus = 3, /obj/item/seeds/random = 2)
products = list(/obj/item/seeds/aloe =3,
/obj/item/seeds/ambrosia = 3,
/obj/item/seeds/apple = 3,
/obj/item/seeds/cotton = 3,
/obj/item/seeds/banana = 3,
/obj/item/seeds/berry = 3,
/obj/item/seeds/cabbage = 3,
/obj/item/seeds/carrot = 3,
/obj/item/seeds/cherry = 3,
/obj/item/seeds/chanter = 3,
/obj/item/seeds/chili = 3,
/obj/item/seeds/cocoapod = 3,
/obj/item/seeds/coffee = 3,
/obj/item/seeds/comfrey =3,
/obj/item/seeds/corn = 3,
/obj/item/seeds/nymph =3,
/obj/item/seeds/eggplant = 3,
/obj/item/seeds/garlic = 3,
/obj/item/seeds/grape = 3,
/obj/item/seeds/grass = 3,
/obj/item/seeds/lemon = 3,
/obj/item/seeds/lime = 3,
/obj/item/seeds/onion = 3,
/obj/item/seeds/orange = 3,
/obj/item/seeds/peanuts = 3,
/obj/item/seeds/pineapple = 3,
/obj/item/seeds/potato = 3,
/obj/item/seeds/poppy = 3,
/obj/item/seeds/pumpkin = 3,
/obj/item/seeds/replicapod = 3,
/obj/item/seeds/wheat/rice = 3,
/obj/item/seeds/soya = 3,
/obj/item/seeds/sunflower = 3,
/obj/item/seeds/sugarcane = 3,
/obj/item/seeds/tea = 3,
/obj/item/seeds/tobacco = 3,
/obj/item/seeds/tomato = 3,
/obj/item/seeds/tower = 3,
/obj/item/seeds/watermelon = 3,
/obj/item/seeds/wheat = 3,
/obj/item/seeds/whitebeet = 3)
contraband = list(/obj/item/seeds/amanita = 2,
/obj/item/seeds/glowshroom = 2,
/obj/item/seeds/liberty = 2,
/obj/item/seeds/nettle = 2,
/obj/item/seeds/plump = 2,
/obj/item/seeds/reishi = 2,
/obj/item/seeds/cannabis = 3,
/obj/item/seeds/starthistle = 2,
/obj/item/seeds/fungus = 3,
/obj/item/seeds/random = 2)
premium = list(/obj/item/reagent_containers/spray/waterflower = 1)
refill_canister = /obj/item/vending_refill/hydroseeds
@@ -1326,41 +1368,129 @@
product_slogans = "Dress for success!;Suited and booted!;It's show time!;Why leave style up to fate? Use AutoDrobe!"
vend_delay = 15
vend_reply = "Thank you for using AutoDrobe!"
products = list(/obj/item/clothing/suit/chickensuit = 1,/obj/item/clothing/head/chicken = 1,/obj/item/clothing/under/gladiator = 1,
/obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1,
/obj/item/clothing/suit/storage/labcoat/mad = 1,/obj/item/clothing/glasses/gglasses = 1,/obj/item/clothing/shoes/jackboots = 1,
/obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/blackskirt = 1,
/obj/item/clothing/suit/toggle/owlwings = 1, /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,
/obj/item/clothing/suit/toggle/owlwings/griffinwings = 1, /obj/item/clothing/under/griffin = 1, /obj/item/clothing/shoes/griffin = 1, /obj/item/clothing/head/griffin = 1,
/obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowlerhat = 1,/obj/item/cane = 1,/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1,
/obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1,/obj/item/clothing/suit/jacket/miljacket = 1,
/obj/item/clothing/suit/jacket/miljacket/white = 1, /obj/item/clothing/suit/jacket/miljacket/desert = 1, /obj/item/clothing/suit/jacket/miljacket/navy = 1,
/obj/item/clothing/under/pirate = 1,/obj/item/clothing/suit/pirate_brown = 1,/obj/item/clothing/suit/pirate_black =1,/obj/item/clothing/under/pirate_rags =1,/obj/item/clothing/head/pirate = 1,/obj/item/clothing/head/bandana = 1,
/obj/item/clothing/head/bandana = 1,/obj/item/clothing/under/soviet = 1,/obj/item/clothing/head/ushanka = 1,/obj/item/clothing/suit/imperium_monk = 1,
/obj/item/clothing/mask/gas/cyborg = 1,/obj/item/clothing/suit/holidaypriest = 1,/obj/item/clothing/head/wizard/marisa/fake = 1,
/obj/item/clothing/suit/wizrobe/marisa/fake = 1,/obj/item/clothing/under/sundress = 1,/obj/item/clothing/head/witchwig = 1,/obj/item/twohanded/staff/broom = 1,
/obj/item/clothing/suit/wizrobe/fake = 1,/obj/item/clothing/head/wizard/fake = 1,/obj/item/twohanded/staff = 3,/obj/item/clothing/mask/gas/clown_hat/sexy = 1,
/obj/item/clothing/under/rank/clown/sexy = 1,/obj/item/clothing/mask/gas/sexymime = 1,/obj/item/clothing/under/sexymime = 1,
/obj/item/clothing/mask/face/bat = 1,/obj/item/clothing/mask/face/bee = 1,/obj/item/clothing/mask/face/bear = 1,/obj/item/clothing/mask/face/raven = 1,/obj/item/clothing/mask/face/jackal = 1,/obj/item/clothing/mask/face/fox = 1,/obj/item/clothing/mask/face/tribal = 1,/obj/item/clothing/mask/face/rat = 1,
products = list(/obj/item/clothing/suit/chickensuit = 1,
/obj/item/clothing/head/chicken = 1,
/obj/item/clothing/under/gladiator = 1,
/obj/item/clothing/head/helmet/gladiator = 1,
/obj/item/clothing/under/gimmick/rank/captain/suit = 1,
/obj/item/clothing/head/flatcap = 1,
/obj/item/clothing/suit/storage/labcoat/mad = 1,
/obj/item/clothing/glasses/gglasses = 1,
/obj/item/clothing/shoes/jackboots = 1,
/obj/item/clothing/under/schoolgirl = 1,
/obj/item/clothing/head/kitty = 1,
/obj/item/clothing/under/blackskirt = 1,
/obj/item/clothing/suit/toggle/owlwings = 1,
/obj/item/clothing/under/owl = 1,
/obj/item/clothing/mask/gas/owl_mask = 1,
/obj/item/clothing/suit/toggle/owlwings/griffinwings = 1,
/obj/item/clothing/under/griffin = 1,
/obj/item/clothing/shoes/griffin = 1,
/obj/item/clothing/head/griffin = 1,
/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/under/suit_jacket = 1,
/obj/item/clothing/head/that =1,
/obj/item/clothing/under/kilt = 1,
/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/glasses/monocle =1,
/obj/item/clothing/head/bowlerhat = 1,
/obj/item/cane = 1,
/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/mask/fakemoustache = 1,
/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,
/obj/item/clothing/head/plaguedoctorhat = 1,
/obj/item/clothing/mask/gas/plaguedoctor = 1,
/obj/item/clothing/suit/apron = 1,
/obj/item/clothing/under/waiter = 1,
/obj/item/clothing/suit/jacket/miljacket = 1,
/obj/item/clothing/suit/jacket/miljacket/white = 1,
/obj/item/clothing/suit/jacket/miljacket/desert = 1,
/obj/item/clothing/suit/jacket/miljacket/navy = 1,
/obj/item/clothing/under/pirate = 1,
/obj/item/clothing/suit/pirate_brown = 1,
/obj/item/clothing/suit/pirate_black =1,
/obj/item/clothing/under/pirate_rags =1,
/obj/item/clothing/head/pirate = 1,
/obj/item/clothing/head/bandana = 1,
/obj/item/clothing/head/bandana = 1,
/obj/item/clothing/under/soviet = 1,
/obj/item/clothing/head/ushanka = 1,
/obj/item/clothing/suit/imperium_monk = 1,
/obj/item/clothing/mask/gas/cyborg = 1,
/obj/item/clothing/suit/holidaypriest = 1,
/obj/item/clothing/head/wizard/marisa/fake = 1,
/obj/item/clothing/suit/wizrobe/marisa/fake = 1,
/obj/item/clothing/under/sundress = 1,
/obj/item/clothing/head/witchwig = 1,
/obj/item/twohanded/staff/broom = 1,
/obj/item/clothing/suit/wizrobe/fake = 1,
/obj/item/clothing/head/wizard/fake = 1,
/obj/item/twohanded/staff = 3,
/obj/item/clothing/mask/gas/clown_hat/sexy = 1,
/obj/item/clothing/under/rank/clown/sexy = 1,
/obj/item/clothing/mask/gas/sexymime = 1,
/obj/item/clothing/under/sexymime = 1,
/obj/item/clothing/mask/face/bat = 1,
/obj/item/clothing/mask/face/bee = 1,
/obj/item/clothing/mask/face/bear = 1,
/obj/item/clothing/mask/face/raven = 1,
/obj/item/clothing/mask/face/jackal = 1,
/obj/item/clothing/mask/face/fox = 1,
/obj/item/clothing/mask/face/tribal = 1,
/obj/item/clothing/mask/face/rat = 1,
/obj/item/clothing/suit/apron/overalls = 1,
/obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, /obj/item/clothing/accessory/blue = 1, /obj/item/clothing/accessory/red = 1, /obj/item/clothing/accessory/black = 1, /obj/item/clothing/accessory/horrible = 1,
/obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1,
/obj/item/clothing/under/jester = 1, /obj/item/clothing/head/jester = 1,
/obj/item/clothing/under/pants/camo = 1, /obj/item/clothing/mask/bandana = 1, /obj/item/clothing/mask/bandana/black = 1,
/obj/item/clothing/shoes/singery = 1,/obj/item/clothing/under/singery = 1,
/obj/item/clothing/shoes/singerb = 1,/obj/item/clothing/under/singerb = 1,
/obj/item/clothing/suit/hooded/carp_costume = 1,/obj/item/clothing/suit/hooded/bee_costume = 1,
/obj/item/clothing/suit/snowman = 1,/obj/item/clothing/head/snowman = 1,
/obj/item/clothing/head/cueball = 1,/obj/item/clothing/under/scratch = 1,
/obj/item/clothing/under/victdress = 1, /obj/item/clothing/under/victdress/red = 1, /obj/item/clothing/suit/victcoat = 1, /obj/item/clothing/suit/victcoat/red = 1,
/obj/item/clothing/under/victsuit = 1, /obj/item/clothing/under/victsuit/redblk = 1, /obj/item/clothing/under/victsuit/red = 1, /obj/item/clothing/suit/tailcoat = 1,
/obj/item/clothing/suit/draculacoat = 1, /obj/item/clothing/head/zepelli = 1,
/obj/item/clothing/under/redhawaiianshirt = 1, /obj/item/clothing/under/pinkhawaiianshirt = 1, /obj/item/clothing/under/bluehawaiianshirt = 1, /obj/item/clothing/under/orangehawaiianshirt = 1)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/gun/magic/wand = 1, /obj/item/clothing/mask/balaclava=1, /obj/item/clothing/mask/horsehead = 2)
premium = list(/obj/item/clothing/suit/hgpirate = 1, /obj/item/clothing/head/hgpiratecap = 1, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman = 1)
/obj/item/clothing/head/rabbitears =1,
/obj/item/clothing/head/sombrero = 1,
/obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/suit/poncho/green = 1,
/obj/item/clothing/suit/poncho/red = 1,
/obj/item/clothing/accessory/blue = 1,
/obj/item/clothing/accessory/red = 1,
/obj/item/clothing/accessory/black = 1,
/obj/item/clothing/accessory/horrible = 1,
/obj/item/clothing/under/maid = 1,
/obj/item/clothing/under/janimaid = 1,
/obj/item/clothing/under/jester = 1,
/obj/item/clothing/head/jester = 1,
/obj/item/clothing/under/pants/camo = 1,
/obj/item/clothing/mask/bandana = 1,
/obj/item/clothing/mask/bandana/black = 1,
/obj/item/clothing/shoes/singery = 1,
/obj/item/clothing/under/singery = 1,
/obj/item/clothing/shoes/singerb = 1,
/obj/item/clothing/under/singerb = 1,
/obj/item/clothing/suit/hooded/carp_costume = 1,
/obj/item/clothing/suit/hooded/bee_costume = 1,
/obj/item/clothing/suit/snowman = 1,
/obj/item/clothing/head/snowman = 1,
/obj/item/clothing/head/cueball = 1,
/obj/item/clothing/under/scratch = 1,
/obj/item/clothing/under/victdress = 1,
/obj/item/clothing/under/victdress/red = 1,
/obj/item/clothing/suit/victcoat = 1,
/obj/item/clothing/suit/victcoat/red = 1,
/obj/item/clothing/under/victsuit = 1,
/obj/item/clothing/under/victsuit/redblk = 1,
/obj/item/clothing/under/victsuit/red = 1,
/obj/item/clothing/suit/tailcoat = 1,
/obj/item/clothing/suit/draculacoat = 1,
/obj/item/clothing/head/zepelli = 1,
/obj/item/clothing/under/redhawaiianshirt = 1,
/obj/item/clothing/under/pinkhawaiianshirt = 1,
/obj/item/clothing/under/bluehawaiianshirt = 1,
/obj/item/clothing/under/orangehawaiianshirt = 1)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
/obj/item/gun/magic/wand = 1,
/obj/item/clothing/mask/balaclava=1,
/obj/item/clothing/mask/horsehead = 2)
premium = list(/obj/item/clothing/suit/hgpirate = 1,
/obj/item/clothing/head/hgpiratecap = 1,
/obj/item/clothing/head/helmet/roman/fake = 1,
/obj/item/clothing/head/helmet/roman/legionaire/fake = 1,
/obj/item/clothing/under/roman = 1,
/obj/item/clothing/shoes/roman = 1,
/obj/item/shield/riot/roman/fake = 1)
refill_canister = /obj/item/vending_refill/autodrobe
/obj/machinery/vending/autodrobe/Initialize(mapload)
@@ -90,6 +90,10 @@
/obj/effect/temp_visual/dir_setting/wraith/out
icon_state = "phase_shift"
/obj/effect/temp_visual/dir_setting/tailsweep
icon_state = "tailsweep"
duration = 4
/obj/effect/temp_visual/wizard
name = "water"
icon = 'icons/mob/mob.dmi'
@@ -231,7 +231,8 @@
create_with_tank = TRUE
/obj/item/flamethrower/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15))
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!</span>")
var/turf/target_turf = get_turf(owner)
log_game("A projectile ([hitby]) detonated a flamethrower tank held by [key_name(owner)] at [COORD(target_turf)]")
@@ -114,7 +114,8 @@
prime()
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
var/turf/T = get_turf(src)
log_game("A projectile ([hitby]) detonated a grenade held by [key_name(owner)] at [COORD(T)]")
@@ -566,7 +567,7 @@
update_icon()
/obj/item/grenade/chem_grenade/saringas
payload_name = "saringas"
payload_name = "sarin gas"
desc = "Contains sarin gas; extremely deadly and fast acting; use with extreme caution."
stage = READY
@@ -39,6 +39,12 @@
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
icon_state = "roman_shield"
item_state = "roman_shield"
materials = list(MAT_METAL=8500)
/obj/item/shield/riot/roman/fake
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
block_chance = 0
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
/obj/item/shield/riot/buckler
name = "wooden buckler"
@@ -389,6 +389,7 @@
..()
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/gun/projectile/automatic/c20r(src)
new /obj/item/suppressor/specialoffer(src)
@@ -403,13 +404,13 @@
new /obj/item/clothing/glasses/chameleon/thermal(src)
/obj/item/storage/backpack/duffel/syndie/med/medicalbundle
desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts."
desc = "A large duffel bag containing a tactical medkit, a medical beam gun and a pair of syndicate magboots."
/obj/item/storage/backpack/duffel/syndie/med/medicalbundle/New()
..()
new /obj/item/storage/firstaid/tactical(src)
new /obj/item/gun/projectile/automatic/l6_saw/toy(src)
new /obj/item/ammo_box/foambox/riot(src)
new /obj/item/clothing/shoes/magboots/syndie(src)
new /obj/item/gun/medbeam(src)
/obj/item/storage/backpack/duffel/syndie/c4/New()
..()
@@ -332,6 +332,7 @@
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/chem_grenade/facid(src) //1
new /obj/item/grenade/chem_grenade/saringas(src) //1
new /obj/item/grenade/gas/plasma(src) //2
new /obj/item/grenade/gas/plasma(src)
new /obj/item/grenade/frag(src) //10
+1 -1
View File
@@ -175,7 +175,7 @@
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.check_shields(src, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return
@@ -74,15 +74,16 @@
temperature = T20C
/turf/simulated/floor/indestructible/hierophant
icon_state = "hierophant1"
name = "floor"
icon = 'icons/turf/floors/hierophant_floor.dmi'
icon_state = "floor"
oxygen = 14
nitrogen = 23
temperature = 300
planetary_atmos = TRUE
desc = "A floor with a square pattern. It's faintly cool to the touch."
smooth = SMOOTH_TRUE
/turf/simulated/floor/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE
/turf/simulated/floor/indestructible/hierophant/two
icon_state = "hierophant2"
/turf/simulated/floor/indestructible/hierophant/two
@@ -29,17 +29,17 @@
return
/turf/simulated/wall/indestructible/attackby(obj/item/I, mob/user, params)
return
return
/turf/simulated/wall/indestructible/attack_hand(mob/user)
return
return
/turf/simulated/wall/indestructible/attack_hulk(mob/user, does_attack_animation = FALSE)
return
/turf/simulated/wall/indestructible/attack_animal(mob/living/simple_animal/M)
return
/turf/simulated/wall/indestructible/mech_melee_attack(obj/mecha/M)
return
@@ -66,9 +66,9 @@
/turf/simulated/wall/indestructible/hierophant
name = "wall"
desc = "A wall made out of smooth, cold stone."
desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern."
icon = 'icons/turf/walls/hierophant_wall.dmi'
icon_state = "hierophant"
icon_state = "wall"
smooth = SMOOTH_TRUE
/turf/simulated/wall/indestructible/uranium
+8
View File
@@ -163,12 +163,20 @@
strip_delay = 100
dog_fashion = null
/obj/item/clothing/head/helmet/roman/fake
desc = "An ancient helmet made of plastic and leather."
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
/obj/item/clothing/head/helmet/roman/legionaire
name = "roman legionaire helmet"
desc = "An ancient helmet made of bronze and leather. Has a red crest on top of it."
icon_state = "roman_c"
item_state = "roman_c"
/obj/item/clothing/head/helmet/roman/legionaire/fake
desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it."
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
/obj/item/clothing/head/helmet/gladiator
name = "gladiator helmet"
desc = "Ave, Imperator, morituri te salutant."
+41 -33
View File
@@ -269,51 +269,59 @@ Gunshots/explosions/opening doors/less rare audio (done)
px = -32
/obj/effect/hallucination/oh_yeah
var/turf/simulated/wall/wall
var/obj/effect/hallucination/simple/bubblegum/bubblegum = null
var/obj/effect/hallucination/simple/bubblegum/bubblegum
var/image/fakebroken
var/image/fakerune
/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/T)
/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/C)
set waitfor = FALSE
..()
target = T
for(var/turf/simulated/wall/W in range(7,target))
target = C
var/turf/simulated/wall/wall
for(var/turf/simulated/wall/W in range(7, target))
wall = W
break
if(wall)
fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER)
var/turf/landing = get_turf(target)
var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3
fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER)
fakebroken.override = TRUE
if(target.client)
target.client.images |= fakebroken
target.client.images |= fakerune
target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1)
bubblegum = new(wall, target)
sleep(10) //ominous wait
var/charged = FALSE //only get hit once
while(get_turf(bubblegum) != landing && target)
bubblegum.forceMove(get_step_towards(bubblegum, landing))
bubblegum.setDir(get_dir(bubblegum, landing))
target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1)
shake_camera(target, 2, 1)
if(bubblegum.Adjacent(target) && !charged)
charged = TRUE
target.Weaken(4)
target.adjustStaminaLoss(40)
step_away(target, bubblegum)
shake_camera(target, 4, 3)
target.visible_message("<span class='warning'>[target] jumps backwards, falling on the ground!</span>","<span class='userdanger'>[bubblegum] slams into you!</span>")
sleep(2)
sleep(30)
qdel(bubblegum)
if(!wall)
qdel(src)
return
fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER)
var/turf/landing = get_turf(target)
var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3
fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER)
fakebroken.override = TRUE
if(target.client)
target.client.images |= fakebroken
target.client.images |= fakerune
target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1)
bubblegum = new(wall, target)
addtimer(CALLBACK(src, .proc/bubble_attack, landing), 10)
/obj/effect/hallucination/oh_yeah/proc/bubble_attack(turf/landing)
var/charged = FALSE //only get hit once
while(get_turf(bubblegum) != landing && target && target.stat != DEAD)
bubblegum.forceMove(get_step_towards(bubblegum, landing))
bubblegum.setDir(get_dir(bubblegum, landing))
target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1)
shake_camera(target, 2, 1)
if(bubblegum.Adjacent(target) && !charged)
charged = TRUE
target.Weaken(4)
target.adjustStaminaLoss(40)
step_away(target, bubblegum)
shake_camera(target, 4, 3)
target.visible_message("<span class='warning'>[target] jumps backwards, falling on the ground!</span>", "<span class='userdanger'>[bubblegum] slams into you!</span>")
sleep(2)
sleep(30)
qdel(src)
/obj/effect/hallucination/oh_yeah/Destroy()
if(target.client)
target.client.images.Remove(fakebroken)
target.client.images.Remove(fakerune)
QDEL_NULL(fakebroken)
QDEL_NULL(fakerune)
QDEL_NULL(bubblegum)
return ..()
/obj/effect/hallucination/singularity_scare
@@ -334,14 +334,6 @@
icon_state = "britcup"
volume = 30
/obj/item/reagent_containers/food/drinks/mushroom_bowl
name = "mushroom bowl"
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_bowl"
w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/drinks/bag
name = "drink bag"
desc = "Normally put in wine boxes, or down pants at stadium events."
+1
View File
@@ -374,6 +374,7 @@
seed.genes += disk.gene.Copy()
if(istype(disk.gene, /datum/plant_gene/reagent))
seed.reagents_from_genes()
disk.gene.apply_vars(seed)
repaint_seed()
update_genes()
+2 -2
View File
@@ -15,7 +15,7 @@
icon_dead = "soybean-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/soya/koi)
reagents_add = list("soybeanoil" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.05)
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05, "soybeanoil" = 0.03)
/obj/item/reagent_containers/food/snacks/grown/soybeans
seed = /obj/item/seeds/soya
@@ -25,7 +25,7 @@
icon_state = "soybeans"
filling_color = "#F0E68C"
bitesize_mod = 2
tastes = list("soybean" = 1)
tastes = list("soy" = 1)
wine_power = 0.2
// Koibean
+5 -5
View File
@@ -46,8 +46,8 @@
desc = "Taste so good, you could die!"
icon_state = "poisonberrypile"
filling_color = "#C71585"
distill_reagent = null
tastes = list("poison-berry" = 1)
distill_reagent = null
wine_power = 0.35
// Death Berries
@@ -70,8 +70,8 @@
desc = "Taste so good, you could die!"
icon_state = "deathberrypile"
filling_color = "#708090"
distill_reagent = null
tastes = list("death-berry" = 1)
distill_reagent = null
wine_power = 0.5
// Glow Berries
@@ -130,8 +130,8 @@
gender = PLURAL
filling_color = "#FF0000"
bitesize_mod = 2
wine_power = 0.3
tastes = list("cherry" = 1)
wine_power = 0.3
// Blue Cherries
/obj/item/seeds/cherry/blue
@@ -152,8 +152,8 @@
icon_state = "bluecherry"
filling_color = "#6495ED"
bitesize_mod = 2
wine_power = 0.5
tastes = list("blue cherry" = 1)
wine_power = 0.5
// Grapes
/obj/item/seeds/grape
@@ -184,8 +184,8 @@
dried_type = /obj/item/reagent_containers/food/snacks/no_raisin
filling_color = "#FF1493"
bitesize_mod = 2
distill_reagent = "wine"
tastes = list("grapes" = 1)
distill_reagent = "wine"
// Green Grapes
/obj/item/seeds/grape/green
+1 -1
View File
@@ -51,7 +51,7 @@
filling_color = "#0000CD"
bitesize_mod = 2
origin_tech = "biotech=4"
tastes = list("chilli" = 1)
tastes = list("chilly" = 1)
wine_power = 0.3
// Ghost Chili
+1 -1
View File
@@ -31,7 +31,6 @@
icon_state = "lime"
filling_color = "#00FF00"
tastes = list("lime" = 1)
distill_reagent = "triple_sec"
// Orange
/obj/item/seeds/orange
@@ -59,6 +58,7 @@
icon_state = "orange"
tastes = list("orange" = 1)
filling_color = "#FFA500"
distill_reagent = "triple_sec"
// Lemon
/obj/item/seeds/lemon
+1 -1
View File
@@ -62,7 +62,7 @@
/obj/item/grown/snapcorn
seed = /obj/item/seeds/corn/snapcorn
name = "snap corn"
desc = "A cob with snap pops"
desc = "A cob with snap pops."
icon_state = "snapcorn"
item_state = "corncob"
w_class = WEIGHT_CLASS_TINY
@@ -27,9 +27,11 @@
// Egg-Plant
/obj/item/seeds/eggplant/eggy
name = "pack of egg-plant seeds"
desc = "These seeds grow to produce berries that look a lot like eggs."
icon_state = "seed-eggy"
species = "eggy"
plantname = "Egg-Plants"
product = /obj/item/reagent_containers/food/snacks/grown/shell/eggy
lifespan = 75
production = 12
+5 -1
View File
@@ -138,6 +138,8 @@
icon_state = "seed-moonflower"
species = "moonflower"
plantname = "Moonflowers"
icon_grow = "moonflower-grow"
icon_dead = "sunflower-dead"
product = /obj/item/reagent_containers/food/snacks/grown/moonflower
mutatelist = list()
reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "plantmatter" = 0.02)
@@ -152,7 +154,7 @@
filling_color = "#E6E6FA"
bitesize_mod = 2
tastes = list("moonflower" = 1)
distill_reagent = "absinthe"
distill_reagent = "absinthe" //It's made from flowers.
// Novaflower
/obj/item/seeds/sunflower/novaflower
@@ -161,6 +163,8 @@
icon_state = "seed-novaflower"
species = "novaflower"
plantname = "Novaflowers"
icon_grow = "novaflower-grow"
icon_dead = "sunflower-dead"
product = /obj/item/grown/novaflower
mutatelist = list()
reagents_add = list("condensedcapsaicin" = 0.25, "capsaicin" = 0.3, "plantmatter" = 0)
+22
View File
@@ -0,0 +1,22 @@
/obj/item/seeds/garlic
name = "pack of garlic seeds"
desc = "A packet of extremely pungent seeds."
icon_state = "seed-garlic"
species = "garlic"
plantname = "Garlic Sprouts"
product = /obj/item/reagent_containers/food/snacks/grown/garlic
yield = 6
potency = 25
growthstages = 3
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
reagents_add = list("garlic" = 0.15, "plantmatter" = 0.1)
/obj/item/reagent_containers/food/snacks/grown/garlic
seed = /obj/item/seeds/garlic
name = "garlic"
desc = "Delicious, but with a potentially overwhelming odor."
icon_state = "garlic"
filling_color = "#C0C9A0"
bitesize_mod = 2
tastes = list("garlic" = 1)
wine_power = 0.1
+1 -10
View File
@@ -38,17 +38,8 @@
continue
grassAmt += 1 + round(G.seed.potency * tile_coefficient)
qdel(G)
var/obj/item/stack/tile/GT = new stacktype(user.loc)
while(grassAmt > GT.max_amount)
GT.amount = GT.max_amount
grassAmt -= GT.max_amount
GT = new stacktype(user.loc)
GT.amount = grassAmt
for(var/obj/item/stack/tile/T in user.loc)
if((T.type == stacktype) && (T.amount < T.max_amount) && (T != GT))
T.attackby(GT, user)
new stacktype(user.drop_location(), grassAmt)
qdel(src)
return
// Carpet
/obj/item/seeds/grass/carpet
+7
View File
@@ -14,6 +14,13 @@
mutatelist = list(/obj/item/seeds/watermelon/holy)
reagents_add = list("water" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.2)
/obj/item/seeds/watermelon/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is swallowing [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
user.gib()
new product(drop_location())
qdel(src)
return OBLITERATION
/obj/item/reagent_containers/food/snacks/grown/watermelon
seed = /obj/item/seeds/watermelon
name = "watermelon"
+3 -3
View File
@@ -14,19 +14,19 @@
growthstages = 3
growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi'
genes = list(/datum/plant_gene/trait/plant_type/weed_hardy)
mutatelist = list(/obj/item/seeds/harebell)
/obj/item/seeds/starthistle/harvest(mob/user)
var/obj/machinery/hydroponics/parent = loc
var/seed_count = yield
if(prob(getYield() * 20))
seed_count++
var/output_loc = parent.Adjacent(user) ? user.loc : parent.loc
for(var/i in 1 to yield+1)
for(var/i in 1 to seed_count)
var/obj/item/seeds/starthistle/harvestseeds = Copy()
harvestseeds.forceMove(output_loc)
parent.update_tray()
// Cabbage
/obj/item/seeds/cabbage
name = "pack of cabbage seeds"
+2 -3
View File
@@ -175,7 +175,7 @@
can_distill = FALSE
/obj/item/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user)
if(istype(user.loc, /turf/space))
if(isspaceturf(user.loc))
return
var/mob/living/simple_animal/hostile/mushroom/M = new /mob/living/simple_animal/hostile/mushroom(user.loc)
M.maxHealth += round(seed.endurance / 4)
@@ -277,8 +277,7 @@
desc = "This mycelium -powers- into mushrooms!"
icon_state = "mycelium-glowcap"
species = "glowcap"
icon_grow = "glowshroom-grow"
icon_dead = "glowshroom-dead"
icon_harvest = "glowcap-harvest"
plantname = "Glowcaps"
product = /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap
genes = list(/datum/plant_gene/trait/glow/red, /datum/plant_gene/trait/cell_charge, /datum/plant_gene/trait/plant_type/fungal_metabolism)
+1 -1
View File
@@ -26,7 +26,7 @@
slice_path = /obj/item/reagent_containers/food/snacks/onion_slice
tastes = list("onion" = 1, "pungentness" = 1)
slices_num = 2
wine_power = 0.2
wine_power = 0.3
wine_flavor = "pungentness"
/obj/item/seeds/onion/red
+30 -26
View File
@@ -1,29 +1,33 @@
// Pineapple!
/obj/item/seeds/pineapple
name = "pack of pineapple seeds"
desc = "These seeds grow into pineapple plants."
icon_state = "seed-pineapple" //NEEDED
species = "pineapple"
plantname = "Pineapple Plant"
product = /obj/item/reagent_containers/food/snacks/grown/pineapple
maturation = 6
lifespan = 55
endurance = 35
growthstages = 4
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
icon_grow = "pineapple-grow" //NEEDED
icon_dead = "pineapple-dead" //NEEDED
genes = list(/datum/plant_gene/trait/repeated_harvest)
reagents_add = list("water" = 0.1, "vitamin" = 0.03, "sugar" = 0.02, "plantmatter" = 0.2)
name = "pack of pineapple seeds"
desc = "Oooooooooooooh!"
icon_state = "seed-pineapple"
species = "pineapple"
plantname = "Pineapple Plant"
product = /obj/item/reagent_containers/food/snacks/grown/pineapple
lifespan = 40
endurance = 30
growthstages = 3
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/apple)
reagents_add = list("vitamin" = 0.02, "plantmatter" = 0.2, "water" = 0.04)
/obj/item/reagent_containers/food/snacks/grown/pineapple
seed = /obj/item/seeds/pineapple
name = "pineapple"
desc = "A soft sweet interior surrounded by a spiky skin."
slice_path = /obj/item/reagent_containers/food/snacks/pineappleslice
slices_num = 4
icon_state = "pineapple"
filling_color = "#e5b437"
w_class = WEIGHT_CLASS_NORMAL
bitesize_mod = 3
tastes = list("pineapple" = 1)
wine_power = 0.4
seed = /obj/item/seeds/pineapple
name = "pineapple"
desc = "A soft sweet interior surrounded by a spiky skin."
icon_state = "pineapple"
force = 4
throwforce = 8
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("stung", "pined")
throw_speed = 1
throw_range = 5
slice_path = /obj/item/reagent_containers/food/snacks/pineappleslice
slices_num = 3
filling_color = "#F6CB0B"
w_class = WEIGHT_CLASS_NORMAL
tastes = list("pineapple" = 1)
wine_power = 0.4
@@ -98,8 +98,6 @@
podman.ckey = ckey_holder
podman.gender = blood_gender
podman.faction |= factions
podman.faction |= "plants"
podman.faction |= "vines" //Pod grown Diona are allied with plants and vines alike.
else //else, one packet of seeds. maybe two
var/seed_count = 1
+8 -8
View File
@@ -44,15 +44,11 @@
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
var/plank_type = /obj/item/stack/sheet/wood
var/plank_name = "wooden planks"
var/list/accepted = list(/obj/item/reagent_containers/food/snacks/grown/tobacco,
var/static/list/accepted = typecacheof(list(/obj/item/reagent_containers/food/snacks/grown/tobacco,
/obj/item/reagent_containers/food/snacks/grown/tea,
/obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris,
/obj/item/reagent_containers/food/snacks/grown/ambrosia/deus,
/obj/item/reagent_containers/food/snacks/grown/wheat)
/obj/item/grown/log/New()
..()
accepted = typecacheof(accepted)
/obj/item/reagent_containers/food/snacks/grown/wheat))
/obj/item/grown/log/attackby(obj/item/W, mob/user, params)
if(is_sharp(W))
@@ -69,7 +65,7 @@
to_chat(user, "<span class='notice'>You add the newly-formed [plank_name] to the stack. It now contains [plank.amount] [plank_name].</span>")
qdel(src)
if(is_type_in_typecache(W, accepted))
if(CheckAccepted(W))
var/obj/item/reagent_containers/food/snacks/grown/leaf = W
if(leaf.dry)
user.show_message("<span class='notice'>You wrap \the [W] around the log, turning it into a torch!</span>")
@@ -84,6 +80,9 @@
else
return ..()
/obj/item/grown/log/proc/CheckAccepted(obj/item/I)
return is_type_in_typecache(I, accepted)
/obj/item/grown/log/tree
seed = null
name = "wood log"
@@ -94,10 +93,11 @@
name = "steel-cap log"
desc = "It's made of metal."
icon_state = "steellogs"
accepted = list()
plank_type = /obj/item/stack/rods
plank_name = "rods"
/obj/item/grown/log/steel/CheckAccepted(obj/item/I)
return FALSE
/////////BONFIRES//////////
+4 -3
View File
@@ -636,9 +636,10 @@
// why, just why
if(S.has_reagent("napalm", 1))
adjustHealth(-round(S.get_reagent_amount("napalm") * 6))
adjustToxic(round(S.get_reagent_amount("napalm") * 7))
adjustWeeds(-rand(5,9))
if(!(myseed.resistance_flags & FIRE_PROOF))
adjustHealth(-round(S.get_reagent_amount("napalm") * 6))
adjustToxic(round(S.get_reagent_amount("napalm") * 7))
adjustWeeds(-rand(5, 9)) //At least give them a small reward if they bother
//Weed Spray
if(S.has_reagent("atrazine", 1))
+13 -1
View File
@@ -10,7 +10,8 @@
/datum/plant_gene/proc/Copy()
return new type
/datum/plant_gene/proc/apply_vars(obj/item/seeds/S) // currently used for fire resist, can prob. be further refactored
return
// Core plant genes store 5 main variables: lifespan, endurance, production, yield, potency
@@ -412,6 +413,17 @@
S.set_up(G.reagents, splat_location)
S.start(smoke_amount)
/datum/plant_gene/trait/fire_resistance // Lavaland
name = "Fire Resistance"
/datum/plant_gene/trait/fire_resistance/apply_vars(obj/item/seeds/S)
if(!(S.resistance_flags & FIRE_PROOF))
S.resistance_flags |= FIRE_PROOF
/datum/plant_gene/trait/fire_resistance/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc)
if(!(G.resistance_flags & FIRE_PROOF))
G.resistance_flags |= FIRE_PROOF
/datum/plant_gene/trait/plant_type // Parent type
name = "you shouldn't see this"
trait_id = "plant_type"
@@ -164,7 +164,6 @@
name = "survival pod medical supply"
desc = "Wall-mounted Medical Equipment dispenser. This one seems just a tiny bit smaller."
req_access = list()
refill_canister = null
products = list(/obj/item/reagent_containers/food/pill/patch/styptic = 5,
/obj/item/reagent_containers/food/pill/patch/silver_sulf = 5,
@@ -342,7 +341,7 @@
/obj/item/shield/changeling,
/obj/item/lava_staff,
/obj/item/katana/energy,
/obj/item/hierophant_staff,
/obj/item/hierophant_club,
/obj/item/storage/toolbox/green/memetic,
/obj/item/gun/projectile/automatic/l6_saw,
/obj/item/gun/magic/staff/chaos,
+118 -44
View File
@@ -1,5 +1,6 @@
/obj/structure/flora/ash
gender = PLURAL
layer = PROJECTILE_HIT_THRESHHOLD_LAYER //sporangiums up don't shoot
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "l_mushroom"
name = "large mushrooms"
@@ -17,42 +18,41 @@
var/harvest_message_high = "You harvest and collect shavings from several mushroom caps."
var/harvested = FALSE
var/base_icon
var/regrowth_time_low = 4800
var/regrowth_time_high = 8400
var/regrowth_time_low = 8 MINUTES
var/regrowth_time_high = 16 MINUTES
/obj/structure/flora/ash/New()
..()
/obj/structure/flora/ash/Initialize(mapload)
. = ..()
base_icon = "[icon_state][rand(1, 4)]"
icon_state = base_icon
if(prob(15))
harvest(null, TRUE)
/obj/structure/flora/ash/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
if(2)
if(prob(80))
qdel(src)
if(3)
if(prob(50))
/obj/structure/flora/ash/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
if(2)
if(prob(80))
qdel(src)
if(3)
if(prob(50))
qdel(src)
/obj/structure/flora/ash/proc/harvest(user, no_drop)
/obj/structure/flora/ash/proc/harvest(user)
if(harvested)
return 0
if(!no_drop)
var/rand_harvested = rand(harvest_amount_low, harvest_amount_high)
if(rand_harvested)
if(user)
var/msg = harvest_message_med
if(rand_harvested == harvest_amount_low)
msg = harvest_message_low
else if(rand_harvested == harvest_amount_high)
msg = harvest_message_high
to_chat(user, "<span class='notice'>[msg]</span>")
for(var/i in 1 to rand_harvested)
new harvest(get_turf(src))
var/rand_harvested = rand(harvest_amount_low, harvest_amount_high)
if(rand_harvested)
if(user)
var/msg = harvest_message_med
if(rand_harvested == harvest_amount_low)
msg = harvest_message_low
else if(rand_harvested == harvest_amount_high)
msg = harvest_message_high
to_chat(user, "<span class='notice'>[msg]</span>")
for(var/i in 1 to rand_harvested)
new harvest(get_turf(src))
icon_state = "[base_icon]p"
name = harvested_name
desc = harvested_desc
@@ -120,7 +120,8 @@
icon_state = "t_mushroom"
name = "numerous mushrooms"
desc = "A large number of mushrooms, some of which have long, fleshy stems. They're radiating light!"
luminosity = 1
light_range = 1.5
light_power = 2.1
harvested_name = "tiny mushrooms"
harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back."
harvest = /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_stem
@@ -166,12 +167,12 @@
desc = "Some shavings from a tall mushroom. With enough, might serve as a bowl."
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_shavings"
list_reagents = list("sugar" = 3, "ethanol" = 2, "stabilizing_agent" = 3, "minttoxin" = 2)
w_class = WEIGHT_CLASS_TINY
seed = /obj/item/seeds/lavaland/polypore
wine_power = 0.2
/obj/item/reagent_containers/food/snacks/grown/ash_flora/New()
..()
/obj/item/reagent_containers/food/snacks/grown/ash_flora/Initialize(mapload)
. = ..()
pixel_x = rand(-4, 4)
pixel_y = rand(-4, 4)
@@ -180,39 +181,105 @@
/obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_leaf
name = "mushroom leaf"
desc = "A leaf, from a mushroom."
list_reagents = list("nutriment" = 3, "vitfro" = 2, "nicotine" = 2)
icon_state = "mushroom_leaf"
seed = /obj/item/seeds/lavaland/porcini
wine_power = 0.4
/obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_cap
name = "mushroom cap"
desc = "The cap of a large mushroom."
list_reagents = list("lsd" = 2, "entpoly" = 4, "psilocybin" = 2)
icon_state = "mushroom_cap"
seed = /obj/item/seeds/lavaland/inocybe
wine_power = 0.7
/obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_stem
name = "mushroom stem"
desc = "A long mushroom stem. It's slightly glowing."
list_reagents = list("tinlux" = 2, "vitamin" = 1, "space_drugs" = 1)
icon_state = "mushroom_stem"
luminosity = 1
seed = /obj/item/seeds/lavaland/ember
wine_power = 0.6
/obj/item/reagent_containers/food/snacks/grown/ash_flora/cactus_fruit
name = "cactus fruit"
list_reagents = list("vitamin" = 2, "nutriment" = 2, "vitfro" = 4)
desc = "A cactus fruit covered in a thick, reddish skin. And some ash."
icon_state = "cactus_fruit"
seed = /obj/item/seeds/lavaland/cactus
wine_power = 0.5
/obj/item/mushroom_bowl
name = "mushroom bowl"
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_bowl"
w_class = WEIGHT_CLASS_SMALL
//SEEDS
/obj/item/seeds/lavaland
name = "lavaland seeds"
desc = "You should never see this."
lifespan = 50
endurance = 25
maturation = 7
production = 4
yield = 4
potency = 15
growthstages = 3
rarity = 20
reagents_add = list("nutriment" = 0.1)
resistance_flags = FIRE_PROOF
/obj/item/seeds/lavaland/cactus
name = "pack of fruiting cactus seeds"
desc = "These seeds grow into fruiting cacti."
icon_state = "seed-cactus"
species = "cactus"
plantname = "Fruiting Cactus"
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/cactus_fruit
genes = list(/datum/plant_gene/trait/fire_resistance)
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
growthstages = 2
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.04, "vitfro" = 0.08)
/obj/item/seeds/lavaland/polypore
name = "pack of polypore mycelium"
desc = "This mycelium grows into bracket mushrooms, also known as polypores. Woody and firm, shaft miners often use them for makeshift crafts."
icon_state = "mycelium-polypore"
species = "polypore"
plantname = "Polypore Mushrooms"
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism, /datum/plant_gene/trait/fire_resistance)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
reagents_add = list("sugar" = 0.06, "ethanol" = 0.04, "stabilizing_agent" = 0.06, "minttoxin" = 0.02)
/obj/item/seeds/lavaland/porcini
name = "pack of porcini mycelium"
desc = "This mycelium grows into Boletus edulus, also known as porcini. Native to the late Earth, but discovered on Lavaland. Has culinary, medicinal and relaxant effects."
icon_state = "mycelium-porcini"
species = "porcini"
plantname = "Porcini Mushrooms"
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_leaf
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism, /datum/plant_gene/trait/fire_resistance)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
reagents_add = list("nutriment" = 0.06, "vitfro" = 0.04, "nicotine" = 0.04)
/obj/item/seeds/lavaland/inocybe
name = "pack of inocybe mycelium"
desc = "This mycelium grows into an inocybe mushroom, a species of Lavaland origin with hallucinatory and toxic effects."
icon_state = "mycelium-inocybe"
species = "inocybe"
plantname = "Inocybe Mushrooms"
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_cap
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism, /datum/plant_gene/trait/fire_resistance)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
reagents_add = list("lsd" = 0.04, "entpoly" = 0.08, "psilocybin" = 0.04)
/obj/item/seeds/lavaland/ember
name = "pack of embershroom mycelium"
desc = "This mycelium grows into embershrooms, a species of bioluminescent mushrooms native to Lavaland."
icon_state = "mycelium-ember"
species = "ember"
plantname = "Embershroom Mushrooms"
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_stem
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism, /datum/plant_gene/trait/glow, /datum/plant_gene/trait/fire_resistance)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
reagents_add = list("tinlux" = 0.04, "vitamin" = 0.02, "space_drugs" = 0.02)
//CRAFTING
//what you can craft with these things
/datum/crafting_recipe/mushroom_bowl
@@ -221,3 +288,10 @@
reqs = list(/obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings = 5)
time = 30
category = CAT_PRIMAL
/obj/item/reagent_containers/food/drinks/mushroom_bowl
name = "mushroom bowl"
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_bowl"
w_class = WEIGHT_CLASS_SMALL
@@ -1,115 +1,190 @@
/obj/item/hierophant_staff
name = "Hierophant's staff"
desc = "A large club with intense magic power infused into it."
icon_state = "hierophant_staff"
item_state = "hierophant_staff"
icon = 'icons/obj/guns/magic.dmi'
#define HIEROPHANT_CLUB_CARDINAL_DAMAGE 30
/obj/item/hierophant_club
name = "hierophant club"
desc = "The strange technology of this large club allows various nigh-magical feats. It used to beat you, but now you can set the beat."
icon_state = "hierophant_club_ready_beacon"
item_state = "hierophant_club_ready_beacon"
icon = 'icons/obj/lavaland/artefacts.dmi'
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
slot_flags = SLOT_BACK
w_class = WEIGHT_CLASS_BULKY
force = 20
hitsound = "swing_hit"
//hitsound = 'sound/weapons/sonic_jackhammer.ogg'
force = 15
attack_verb = list("clubbed", "beat", "pummeled")
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
var/chaser_cooldown = 81 //how long the cooldown between firing chasers at mobs is
var/chaser_timer = 0 //what our current chaser cooldown is
var/chaser_speed = 0.8 //how fast our chasers are
var/timer = 0 //what our current cooldown is
var/blast_range = 3 //how long the cardinal blast's walls are
var/obj/effect/hierophant/rune //the associated rune we teleport to
var/blast_range = 13 //how long the cardinal blast's walls are
var/obj/effect/hierophant/beacon //the associated beacon we teleport to
var/teleporting = FALSE //if we ARE teleporting
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
/obj/item/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
/obj/item/hierophant_club/examine(mob/user)
..()
to_chat(user, "<span class='hierophant_warning'>The[beacon ? " beacon is not currently":"re is a beacon"] attached.</span>")
/obj/item/hierophant_club/suicide_act(mob/living/user)
atom_say("Xverwpsgexmrk...")
user.visible_message("<span class='suicide'>[user] holds [src] into the air! It looks like [user.p_theyre()] trying to commit suicide!</span>")
new/obj/effect/temp_visual/hierophant/telegraph(get_turf(user))
playsound(user,'sound/machines/airlock_open.ogg', 75, TRUE)
user.visible_message("<span class='hierophant_warning'>[user] fades out, leaving [user.p_their()] belongings behind!</span>")
for(var/obj/item/I in user)
if(I != src)
user.unEquip(I)
for(var/turf/T in RANGE_TURFS(1, user))
var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, TRUE)
B.damage = 0
user.unEquip(src) //Drop us last, so it goes on top of their stuff
qdel(user)
return OBLITERATION
/obj/item/hierophant_club/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
..()
var/turf/T = get_turf(target)
if(!T || timer > world.time)
return
calculate_anger_mod(user)
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
if(proximity_flag)
spawn(0)
aoe_burst(T, user)
INVOKE_ASYNC(src, .proc/aoe_burst, T, user)
add_attack_logs(user, target, "Fired 3x3 blast at [src]")
else
if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
spawn(0)
cardinal_blasts(T, user)
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user)
timer = world.time + cooldown_time
else if(target in view(5, get_turf(user))) //if the target is in view, hit it
timer = world.time + cooldown_time
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
chaser_timer = world.time + chaser_cooldown
new /obj/effect/temp_visual/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(user), user, target, chaser_speed, friendly_fire_check)
C.damage = 30
C.monster_damage_boost = FALSE
add_attack_logs(user, target, "Fired a chaser at [src]")
else
spawn(0)
cardinal_blasts(T, user) //otherwise, just do cardinal blast
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
add_attack_logs(user, target, "Fired cardinal blast at [src]")
else
to_chat(user, "<span class='warning'>That target is out of range!</span>") //too far away
to_chat(user, "<span class='warning'>That target is out of range!</span>" )
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
/obj/item/hierophant_staff/ui_action_click(mob/user, actiontype)
/obj/item/hierophant_club/proc/calculate_anger_mod(mob/user) //we get stronger as the user loses health
chaser_cooldown = initial(chaser_cooldown)
cooldown_time = initial(cooldown_time)
chaser_speed = initial(chaser_speed)
blast_range = initial(blast_range)
if(isliving(user))
var/mob/living/L = user
var/health_percent = L.health / L.maxHealth
chaser_cooldown += round(health_percent * 20) //two tenths of a second for each missing 10% of health
cooldown_time += round(health_percent * 10) //one tenth of a second for each missing 10% of health
chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health
blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health
/obj/item/hierophant_club/update_icon()
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
item_state = icon_state
if(ismob(loc))
var/mob/M = loc
M.update_inv_l_hand()
M.update_inv_r_hand()
M.update_inv_back()
/obj/item/hierophant_club/proc/prepare_icon_update()
update_icon()
sleep(timer - world.time)
update_icon()
/obj/item/hierophant_club/ui_action_click(mob/user, actiontype)
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
friendly_fire_check = !friendly_fire_check
to_chat(user, "<span class='warning'>You toggle friendly fire [friendly_fire_check ? "off":"on"]!</span>")
return
if(user.is_in_active_hand(src) && user.is_in_inactive_hand(src)) //you need to hold the staff to teleport
to_chat(user, "<span class='warning'>You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!</span>")
if(timer > world.time)
return
if(!rune)
if(user.is_in_active_hand(src) && user.is_in_inactive_hand(src)) //you need to hold the staff to teleport
to_chat(user, "<span class='warning'>You need to hold the club in your hands to [beacon ? "teleport with it":"detach the beacon"]!</span>")
return
if(!beacon || QDELETED(beacon))
if(isturf(user.loc))
user.visible_message("<span class='hierophant_warning'>[user] holds [src] carefully in front of [user.p_them()], moving it in a strange pattern...</span>", \
"<span class='notice'>You start creating a hierophant rune to teleport to...</span>")
user.visible_message("<span class='hierophant_warning'>[user] starts fiddling with [src]'s pommel...</span>", \
"<span class='notice'>You start detaching the hierophant beacon...</span>")
timer = world.time + 51
if(do_after(user, 50, target = user))
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(do_after(user, 50, target = user) && !beacon)
var/turf/T = get_turf(user)
playsound(T,'sound/magic/blind.ogg', 200, 1, -4)
playsound(T,'sound/magic/blind.ogg', 200, TRUE, -4)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
rune = H
beacon = new/obj/effect/hierophant(T)
user.update_action_buttons_icon()
user.visible_message("<span class='hierophant_warning'>[user] creates a strange rune beneath [user.p_them()]!</span>", \
"<span class='hierophant'>You create a hierophant rune, which you can teleport yourself and any allies to at any time!</span>\n\
<span class='notice'>You can remove the rune to place a new one by striking it with the staff.</span>")
user.visible_message("<span class='hierophant_warning'>[user] places a strange machine beneath [user.p_their()] feet!</span>", \
"<span class='hierophant'>You detach the hierophant beacon, allowing you to teleport yourself and any allies to it at any time!</span>\n\
<span class='notice'>You can remove the beacon to place it again by striking it with the club.</span>")
else
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
else
to_chat(user, "<span class='warning'>You need to be on solid ground to produce a rune!</span>")
to_chat(user, "<span class='warning'>You need to be on solid ground to detach the beacon!</span>")
return
if(get_dist(user, rune) <= 2) //rune too close abort
to_chat(user, "<span class='warning'>You are too close to the rune to teleport to it!</span>")
if(get_dist(user, beacon) <= 2) //beacon too close abort
to_chat(user, "<span class='warning'>You are too close to the beacon to teleport to it!</span>")
return
if(is_blocked_turf(get_turf(rune)))
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
if(is_blocked_turf(get_turf(beacon), TRUE))
to_chat(user, "<span class='warning'>The beacon is blocked by something, preventing teleportation!</span>")
return
if(!isturf(user.loc))
to_chat(user, "<span class='warning'>You don't have enough space to teleport from here!</span>")
return
teleporting = TRUE //start channel
user.update_action_buttons_icon()
user.visible_message("<span class='hierophant_warning'>[user] starts to glow faintly...</span>")
timer = world.time + 50
if(do_after(user, 40, target = user) && rune)
var/turf/T = get_turf(rune)
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_on"
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE1 = new /obj/effect/temp_visual/hierophant/telegraph/edge(user.loc)
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE2 = new /obj/effect/temp_visual/hierophant/telegraph/edge(beacon.loc)
if(do_after(user, 40, target = user) && user && beacon)
var/turf/T = get_turf(beacon)
var/turf/source = get_turf(user)
if(is_blocked_turf(T))
if(is_blocked_turf(T, TRUE))
teleporting = FALSE
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
to_chat(user, "<span class='warning'>The beacon is blocked by something, preventing teleportation!</span>")
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_off"
return
new /obj/effect/temp_visual/hierophant/telegraph(T, user)
new /obj/effect/temp_visual/hierophant/telegraph(source, user)
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/magic/wand_teleport.ogg', 200, 1)
playsound(source,'sound/magic/blink.ogg', 200, 1)
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
playsound(T,'sound/magic/wand_teleport.ogg', 200, TRUE)
playsound(source,'sound/machines/airlock_open.ogg', 200, TRUE)
if(!do_after(user, 3, target = user) || !user || !beacon || QDELETED(beacon)) //no walking away shitlord
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(beacon)
beacon.icon_state = "hierophant_tele_off"
return
if(is_blocked_turf(T))
if(is_blocked_turf(T, TRUE))
teleporting = FALSE
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
to_chat(user, "<span class='warning'>The beacon is blocked by something, preventing teleportation!</span>")
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_off"
return
add_attack_logs(user, rune, "Teleported self from ([source.x],[source.y],[source.z]) to ([T.x],[T.y],[T.z])")
add_attack_logs(user, beacon, "Teleported self from ([AREACOORD(source)]) to ([AREACOORD(beacon)])")
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, user)
for(var/t in RANGE_TURFS(1, T))
@@ -119,18 +194,24 @@
var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies
B.damage = 30
for(var/mob/living/L in range(1, source))
spawn(0)
teleport_mob(source, L, T, user) //regardless, take all mobs near us along
INVOKE_ASYNC(src, .proc/teleport_mob, source, L, T, user) //regardless, take all mobs near us along
sleep(6) //at this point the blasts detonate
if(beacon)
beacon.icon_state = "hierophant_tele_off"
else
qdel(TE1)
qdel(TE2)
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(beacon)
beacon.icon_state = "hierophant_tele_off"
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
/obj/item/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
/obj/item/hierophant_club/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE))
return
animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
sleep(1)
@@ -152,19 +233,19 @@
if(user != M)
add_attack_logs(user, M, "Teleported from ([source.x],[source.y],[source.z])")
/obj/item/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
/obj/item/hierophant_club/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
if(!T)
return
new /obj/effect/temp_visual/hierophant/telegraph/cardinal(T, user)
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
playsound(T,'sound/effects/bin_close.ogg', 200, TRUE)
sleep(2)
new /obj/effect/temp_visual/hierophant/blast(T, user, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, friendly_fire_check)
B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE
B.monster_damage_boost = FALSE
for(var/d in cardinal)
spawn(0)
blast_wall(T, d, user)
INVOKE_ASYNC(src, .proc/blast_wall, T, d, user)
/obj/item/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
/obj/item/hierophant_club/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
if(!T)
return
var/range = blast_range
@@ -173,16 +254,20 @@
for(var/i in 1 to range)
if(!J)
return
new /obj/effect/temp_visual/hierophant/blast(J, user, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/blast/B = new(J, user, friendly_fire_check)
B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE
B.monster_damage_boost = FALSE
previousturf = J
J = get_step(previousturf, dir)
/obj/item/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
/obj/item/hierophant_club/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
if(!T)
return
new /obj/effect/temp_visual/hierophant/telegraph(T, user)
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
playsound(T,'sound/effects/bin_close.ogg', 200, TRUE)
sleep(2)
for(var/t in RANGE_TURFS(1, T))
new /obj/effect/temp_visual/hierophant/blast(t, user, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/blast/B = new(t, user, friendly_fire_check)
B.damage = 15 //keeps monster damage boost due to lower damage
#undef HIEROPHANT_CLUB_CARDINAL_DAMAGE
@@ -126,7 +126,6 @@
modkit_design = /datum/design/unique_modkit/bounty
/datum/design/unique_modkit
category = list("Mining", "Cyborg Upgrade Modules") //can't be normally obtained
build_type = PROTOLATHE | MECHFAB
/datum/design/unique_modkit/offensive_turf_aoe
@@ -135,6 +134,7 @@
id = "hyperaoemod"
materials = list(MAT_METAL = 7000, MAT_GLASS = 3000, MAT_SILVER= 3000, MAT_GOLD = 3000, MAT_DIAMOND = 4000)
build_path = /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs
category = list("Mining", "Cyborg Upgrade Modules")
/datum/design/unique_modkit/rapid_repeater
name = "Kinetic Accelerator Rapid Repeater Mod"
@@ -142,6 +142,7 @@
id = "repeatermod"
materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_URANIUM = 8000, MAT_BLUESPACE = 2000)
build_path = /obj/item/borg/upgrade/modkit/cooldown/repeater
category = list("Mining", "Cyborg Upgrade Modules")
/datum/design/unique_modkit/resonator_blast
name = "Kinetic Accelerator Resonator Blast Mod"
@@ -149,6 +150,7 @@
id = "resonatormod"
materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_SILVER= 5000, MAT_URANIUM = 5000)
build_path = /obj/item/borg/upgrade/modkit/resonator_blasts
category = list("Mining", "Cyborg Upgrade Modules")
/datum/design/unique_modkit/bounty
name = "Kinetic Accelerator Death Syphon Mod"
@@ -156,4 +158,5 @@
id = "bountymod"
materials = list(MAT_METAL = 4000, MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_BLUESPACE = 4000)
reagents_list = list("blood" = 40)
build_path = /obj/item/borg/upgrade/modkit/bounty
build_path = /obj/item/borg/upgrade/modkit/bounty
category = list("Mining", "Cyborg Upgrade Modules")
@@ -59,7 +59,8 @@ In all, this is a lot like the monkey code. /N
return 0
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
if(..())
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
@@ -328,7 +328,7 @@ This function restores all organs.
return 0
/mob/living/carbon/human/proc/get_organ(zone)
/mob/living/carbon/human/get_organ(zone)
if(!zone)
zone = "chest"
if(zone in list("eyes", "mouth"))
@@ -437,16 +437,17 @@ emp_act
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>")
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(..())
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(check_shields(M, damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
return 0
if(check_shields(M, damage, "the [M.name]", MELEE_ATTACK, M.armour_penetration))
return FALSE
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
if(!affecting)
affecting = get_organ("chest")
affecting.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
var/obj/item/organ/external/affected = src.get_organ(dam_zone)
if(affected)
affected.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data
apply_damage(damage, M.melee_damage_type, affecting, armor)
updatehealth("animal attack")
@@ -519,7 +519,7 @@
to_chat(M, "<span class='warning'>You can't use your hand.</span>")
return
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK))
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
add_attack_logs(M, H, "Melee attacked with fists (miss/block)")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
return FALSE
@@ -258,7 +258,8 @@
M.updatehealth()
/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M)
if(..())
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
attacked += 10
adjustBruteLoss(damage)
+9 -9
View File
@@ -303,17 +303,17 @@
return
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src].")
return 0
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>")
add_attack_logs(M, src, "Animal attacked")
return 1
return FALSE
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>")
add_attack_logs(M, src, "Animal attacked")
return TRUE
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
+2 -8
View File
@@ -227,14 +227,8 @@
// See software.dm for Topic()
/mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M)
if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src].")
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("<span class='danger'>[M]</span> [M.attacktext] [src]!", 1)
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
add_attack_logs(M, src, "Animal attacked for [damage] damage")
adjustBruteLoss(damage)
@@ -20,7 +20,8 @@
return
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
if(..())
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
@@ -53,9 +53,10 @@
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
if(..())
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
attack_threshold_check(damage, M.melee_damage_type)
return attack_threshold_check(damage, M.melee_damage_type)
/mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M)
..()
@@ -80,7 +80,7 @@
else
to_chat(M, "<span class='cult'>You cannot repair your own dents, as you have none!</span>")
else if(src != M)
..()
return ..()
/mob/living/simple_animal/hostile/construct/narsie_act()
@@ -30,7 +30,7 @@ Difficulty: Medium
icon = 'icons/mob/alienqueen.dmi'
light_color = "#E4C7C5"
speak_emote = list("roars")
speed = 1
speed = 3
move_to_delay = 3
projectiletype = /obj/item/projectile/kinetic/miner
projectilesound = 'sound/weapons/kenetic_accel.ogg'
@@ -1,3 +1,8 @@
#define BUBBLEGUM_SMASH (health <= maxHealth * 0.5) // angery
#define BUBBLEGUM_CAN_ENRAGE (enrage_till + (enrage_time * 2) <= world.time)
#define BUBBLEGUM_IS_ENRAGED (enrage_till > world.time)
/*
BUBBLEGUM
@@ -5,14 +10,16 @@ BUBBLEGUM
Bubblegum spawns randomly wherever a lavaland creature is able to spawn. It is the most powerful slaughter demon in existence.
Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size.
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power
It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target.
If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it.
If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood.
At half health, it will either charge three times or warp, then charge, instead of doing a single charge.
It leaves blood trails behind wherever it goes, its clones do as well.
It tries to strike at its target through any bloodpools under them; if it fails to do that.
If it does warp it will enter an enraged state, becoming immune to all projectiles, becoming much faster, and dealing damage and knockback to anything that gets in the cloud around it.
It may summon clones charging from all sides, one of these charges being bubblegum himself.
It can charge at its target, and also heavily damaging anything directly hit in the charge.
If at half health it will start to charge from all sides with clones.
When Bubblegum dies, it leaves behind a chest that can contain three things:
When Bubblegum dies, it leaves behind a H.E.C.K. mining suit as well as a chest that can contain three things:
1. A bottle that, when activated, drives everyone nearby into a frenzy
2. A contract that marks for death the chosen target
3. A spellblade that can slice off limbs at range
@@ -37,19 +44,31 @@ Difficulty: Hard
armour_penetration = 40
melee_damage_lower = 40
melee_damage_upper = 40
speed = 1
move_to_delay = 10
ranged = 1
speed = 5
move_to_delay = 5
retreat_distance = 5
minimum_distance = 5
rapid_melee = 8 // every 1/4 second
melee_queue_distance = 20 // as far as possible really, need this because of blood warp
ranged = TRUE
pixel_x = -32
del_on_death = 1
del_on_death = TRUE
crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher)
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
var/charging = 0
blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = FALSE
var/enrage_till = 0
var/enrage_time = 70
var/revving_charge = FALSE
internal_type = /obj/item/gps/internal/bubblegum
medal_type = BOSS_MEDAL_BUBBLEGUM
score_type = BUBBLEGUM_SCORE
deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... "
death_sound = 'sound/misc/enter_blood.ogg'
attack_action_types = list(/datum/action/innate/megafauna_attack/triple_charge,
/datum/action/innate/megafauna_attack/hallucination_charge,
/datum/action/innate/megafauna_attack/hallucination_surround,
/datum/action/innate/megafauna_attack/blood_warp)
/obj/item/gps/internal/bubblegum
icon_state = null
@@ -57,54 +76,6 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount)
if(amount > 0 && prob(25))
var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc)
if(prob(40))
step(B, pick(cardinal))
else
B.dir = pick(cardinal)
. = ..()
/obj/effect/decal/cleanable/blood/gibs/bubblegum
name = "thick blood"
desc = "Thick, splattered blood."
random_icon_states = list("gib3", "gib5", "gib6")
amount = 20
/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life(seconds, times_fired)
..()
move_to_delay = Clamp((health/maxHealth) * 10, 5, 10)
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
anger_modifier = Clamp(((maxHealth - health)/60),0,20)
if(charging)
return
ranged_cooldown = world.time + ranged_cooldown_time
var/warped = FALSE
if(!try_bloodattack())
spawn(0)
blood_spray()
warped = blood_warp()
if(warped && prob(100 - anger_modifier))
return
if(prob(90 - anger_modifier) || slaughterlings())
if(health > maxHealth * 0.5)
spawn(0)
charge()
else
if(prob(70) || warped)
spawn(0)
triple_charge()
else
spawn(0)
warp_charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload)
. = ..()
if(true_spawn)
@@ -112,88 +83,118 @@ Difficulty: Hard
if(B != src)
qdel(src) //There can be only one
return
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
if(istype(loc, /obj/effect/dummy/slaughter))
bloodspell.phased = 1
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y)
if(!charging)
..()
/datum/action/innate/megafauna_attack/triple_charge
name = "Triple Charge"
icon_icon = 'icons/mob/actions/actions.dmi'
button_icon_state = "sniper_zoom"
chosen_message = "<span class='colossus'>You are now triple charging at the target you click on.</span>"
chosen_attack_num = 1
/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget()
if(!charging)
return ..()
/datum/action/innate/megafauna_attack/hallucination_charge
name = "Hallucination Charge"
icon_icon = 'icons/effects/bubblegum.dmi'
button_icon_state = "smack ya one"
chosen_message = "<span class='colossus'>You are now charging with hallucinations at the target you click on.</span>"
chosen_attack_num = 2
/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance)
if(!charging)
..()
/datum/action/innate/megafauna_attack/hallucination_surround
name = "Surround Target"
icon_icon = 'icons/turf/walls/wall.dmi'
button_icon_state = "wall"
chosen_message = "<span class='colossus'>You are now surrounding the target you click on with hallucinations.</span>"
chosen_attack_num = 3
/mob/living/simple_animal/hostile/megafauna/bubblegum/MoveToTarget(list/possible_targets)
if(!charging)
..()
/datum/action/innate/megafauna_attack/blood_warp
name = "Blood Warp"
icon_icon = 'icons/effects/blood.dmi'
button_icon_state = "floor1"
chosen_message = "<span class='colossus'>You are now warping to blood around your clicked position.</span>"
chosen_attack_num = 4
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
if(charging)
new /obj/effect/temp_visual/decoy/fading(loc, src)
DestroySurroundings()
. = ..()
if(!stat && .)
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
DestroySurroundings()
return
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge()
blood_warp()
charge()
anger_modifier = Clamp(((maxHealth - health)/60),0,20)
enrage_time = initial(enrage_time) * Clamp(anger_modifier / 20, 0.5, 1)
ranged_cooldown = world.time + 50
if(client)
switch(chosen_attack)
if(1)
triple_charge()
if(2)
hallucination_charge()
if(3)
surround_with_hallucinations()
if(4)
blood_warp()
return
if(!try_bloodattack() || prob(25 + anger_modifier))
blood_warp()
if(!BUBBLEGUM_SMASH)
triple_charge()
else
if(prob(50 + anger_modifier))
hallucination_charge()
else
surround_with_hallucinations()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge()
charge()
charge()
charge()
charge(delay = 6)
charge(delay = 4)
charge(delay = 2)
SetRecoveryTime(15)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
var/turf/T = get_turf(target)
if(!T || T == loc)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/hallucination_charge()
if(!BUBBLEGUM_SMASH || prob(33))
hallucination_charge_around(times = 6, delay = 8)
SetRecoveryTime(10)
else
hallucination_charge_around(times = 4, delay = 9)
hallucination_charge_around(times = 4, delay = 8)
hallucination_charge_around(times = 4, delay = 7)
triple_charge()
SetRecoveryTime(20)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/surround_with_hallucinations()
for(var/i = 1 to 5)
INVOKE_ASYNC(src, .proc/hallucination_charge_around, 2, 8, 2, 0, 4)
if(ismob(target))
charge(delay = 6)
else
SLEEP_CHECK_DEATH(6)
SetRecoveryTime(20)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge(atom/chargeat = target, delay = 3, chargepast = 2)
if(!chargeat)
return
new /obj/effect/temp_visual/dragon_swoop(T)
charging = 1
var/chargeturf = get_turf(chargeat)
if(!chargeturf)
return
var/dir = get_dir(src, chargeturf)
var/turf/T = get_ranged_target_turf(chargeturf, dir, chargepast)
if(!T)
return
new /obj/effect/temp_visual/dragon_swoop/bubblegum(T)
charging = TRUE
revving_charge = TRUE
DestroySurroundings()
walk(src, 0)
dir = get_dir(src, T)
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src)
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5)
sleep(5)
throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
setDir(dir)
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc,src)
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 3)
SLEEP_CHECK_DEATH(delay)
revving_charge = FALSE
var/movespeed = 0.7
walk_towards(src, T, movespeed)
SLEEP_CHECK_DEATH(get_dist(src, T) * movespeed)
walk(src, 0) // cancel the movement
try_bloodattack()
if(target)
Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A)
if(charging)
if(isturf(A) || isobj(A) && A.density)
A.ex_act(2)
DestroySurroundings()
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/A)
if(!charging)
return ..()
else if(isliving(A))
var/mob/living/L = A
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
L.apply_damage(40, BRUTE)
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
L.throw_at(throwtarget, 3)
charging = 0
charging = FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood()
var/list/targets = ListTargets()
@@ -206,9 +207,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
var/list/targets = get_mobs_on_blood()
if(targets.len)
spawn(0)
bloodattack(targets, prob(50))
INVOKE_ASYNC(src, .proc/bloodattack, targets, prob(50))
return TRUE
return FALSE
@@ -249,14 +248,14 @@ Difficulty: Hard
new /obj/effect/temp_visual/bubblegum_hands/rightsmack(T)
else
new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T)
sleep(2.5)
SLEEP_CHECK_DEATH(4)
for(var/mob/living/L in T)
if(!faction_check_mob(L))
to_chat(L, "<span class='userdanger'>[src] rends you!</span>")
playsound(T, attack_sound, 100, 1, -1)
var/limb_to_hit = pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg")
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
sleep(3)
playsound(T, attack_sound, 100, TRUE, -1)
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
L.apply_damage(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
SLEEP_CHECK_DEATH(3)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness)
if(handedness)
@@ -265,18 +264,221 @@ Difficulty: Hard
else
new /obj/effect/temp_visual/bubblegum_hands/leftpaw(T)
new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T)
sleep(6)
SLEEP_CHECK_DEATH(6)
for(var/mob/living/L in T)
if(!faction_check_mob(L))
to_chat(L, "<span class='userdanger'>[src] drags you through the blood!</span>")
playsound(T, 'sound/misc/enter_blood.ogg', 100, 1, -1)
var/turf/targetturf = get_step(src, dir)
L.forceMove(targetturf)
playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, 1, -1)
if(L.stat != CONSCIOUS)
spawn(2)
devour(L)
sleep(1)
to_chat(L, "<span class='userdanger'>[src] drags you through the blood!</span>")
playsound(T, 'sound/misc/enter_blood.ogg', 100, TRUE, -1)
var/turf/targetturf = get_step(src, dir)
L.forceMove(targetturf)
playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, TRUE, -1)
addtimer(CALLBACK(src, .proc/devour, L), 2)
SLEEP_CHECK_DEATH(1)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
if(Adjacent(target))
return FALSE
var/list/can_jaunt = get_pools(get_turf(src), 1)
if(!can_jaunt.len)
return FALSE
var/list/pools = get_pools(get_turf(target), 5)
var/list/pools_to_remove = get_pools(get_turf(target), 4)
pools -= pools_to_remove
if(!pools.len)
return FALSE
var/obj/effect/temp_visual/decoy/DA = new /obj/effect/temp_visual/decoy(loc,src)
DA.color = "#FF0000"
var/oldtransform = DA.transform
DA.transform = matrix()*2
animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 3)
SLEEP_CHECK_DEATH(3)
qdel(DA)
var/obj/effect/decal/cleanable/blood/found_bloodpool
pools = get_pools(get_turf(target), 5)
pools_to_remove = get_pools(get_turf(target), 4)
pools -= pools_to_remove
if(pools.len)
shuffle_inplace(pools)
found_bloodpool = pick(pools)
if(found_bloodpool)
visible_message("<span class='danger'>[src] sinks into the blood...</span>")
playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, TRUE, -1)
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, TRUE, -1)
visible_message("<span class='danger'>And springs back out!</span>")
blood_enrage()
return TRUE
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/be_aggressive()
if(BUBBLEGUM_IS_ENRAGED)
return TRUE
if(isliving(target))
var/mob/living/livingtarget = target
return (livingtarget.stat != CONSCIOUS || livingtarget.lying)
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_retreat_distance()
return (be_aggressive() ? null : initial(retreat_distance))
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_minimum_distance()
return (be_aggressive() ? 1 : initial(minimum_distance))
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/update_approach()
retreat_distance = get_retreat_distance()
minimum_distance = get_minimum_distance()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage()
if(!BUBBLEGUM_CAN_ENRAGE)
return FALSE
enrage_till = world.time + enrage_time
update_approach()
change_move_delay(3.75)
var/newcolor = rgb(149, 10, 10)
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
var/datum/callback/cb = CALLBACK(src, .proc/blood_enrage_end)
addtimer(cb, enrage_time)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage_end(newcolor = rgb(149, 10, 10))
update_approach()
change_move_delay()
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/change_move_delay(newmove = initial(move_to_delay))
move_to_delay = newmove
speed = move_to_delay
handle_automated_action() // need to recheck movement otherwise move_to_delay won't update until the next checking aka will be wrong speed for a bit
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
. = list()
for(var/obj/effect/decal/cleanable/nearby in view(T, range))
if(nearby.can_bloodcrawl_in())
. += nearby
/obj/effect/decal/cleanable/blood/bubblegum
bloodiness = 0
/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/hallucination_charge_around(times = 4, delay = 6, chargepast = 0, useoriginal = 1, radius)
var/startingangle = rand(1, 360)
if(!target)
return
var/turf/chargeat = get_turf(target)
var/srcplaced = FALSE
if(!radius)
radius = times
for(var/i = 1 to times)
var/ang = (startingangle + 360/times * i)
if(!chargeat)
return
var/turf/place = locate(chargeat.x + cos(ang) * radius, chargeat.y + sin(ang) * radius, chargeat.z)
if(!place)
continue
if(!nest || nest && nest.parent && get_dist(nest.parent, place) <= nest_range)
if(!srcplaced && useoriginal)
forceMove(place)
srcplaced = TRUE
continue
var/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/B = new /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination(loc)
B.forceMove(place)
INVOKE_ASYNC(B, .proc/charge, chargeat, delay, chargepast)
if(useoriginal)
charge(chargeat, delay, chargepast)
/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE)
. = ..()
if(. > 0 && prob(25))
var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc)
if(prob(40))
step(B, pick(cardinal))
else
B.setDir(pick(cardinal))
/obj/effect/decal/cleanable/blood/gibs/bubblegum
name = "thick blood"
desc = "Thick, splattered blood."
random_icon_states = list("gib3", "gib5", "gib6")
bloodiness = 20
/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon)
if(!charging)
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget()
if(!charging)
. = ..()
if(.)
recovery_time = world.time + 20 // can only attack melee once every 2 seconds but rapid_melee gives higher priority
/mob/living/simple_animal/hostile/megafauna/bubblegum/bullet_act(obj/item/projectile/P)
if(BUBBLEGUM_IS_ENRAGED)
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons while enraged!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 300, TRUE)
return
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target)
if(severity >= EXPLODE_LIGHT)
return
severity = EXPLODE_LIGHT // puny mortals
return ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination))
return TRUE
return ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance)
if(!charging)
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/MoveToTarget(list/possible_targets)
if(!charging)
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
update_approach()
if(revving_charge)
return FALSE
if(charging)
new /obj/effect/temp_visual/decoy/fading(loc,src)
DestroySurroundings()
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Moved(atom/OldLoc, Dir, Forced = FALSE)
if(Dir)
new /obj/effect/decal/cleanable/blood/bubblegum(loc)
if(charging)
DestroySurroundings()
playsound(src, 'sound/effects/meteorimpact.ogg', 200, TRUE, 2, TRUE)
return ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A)
if(charging)
if(isturf(A) || isobj(A) && A.density)
A.ex_act(EXPLODE_HEAVY)
DestroySurroundings()
if(isliving(A))
var/mob/living/L = A
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] tramples you into the ground!</span>")
forceMove(get_turf(L))
L.apply_damage(istype(src, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination) ? 15 : 30, BRUTE)
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, TRUE)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
..()
/obj/effect/temp_visual/dragon_swoop/bubblegum
duration = 10
/obj/effect/temp_visual/bubblegum_hands
icon = 'icons/effects/bubblegum.dmi'
@@ -290,11 +492,11 @@ Difficulty: Hard
/obj/effect/temp_visual/bubblegum_hands/rightpaw
icon_state = "rightpawgrab"
layer = MOB_LAYER - 0.1
layer = BELOW_MOB_LAYER
/obj/effect/temp_visual/bubblegum_hands/leftpaw
icon_state = "leftpawgrab"
layer = MOB_LAYER - 0.1
layer = BELOW_MOB_LAYER
/obj/effect/temp_visual/bubblegum_hands/rightsmack
icon_state = "rightsmack"
@@ -302,94 +504,48 @@ Difficulty: Hard
/obj/effect/temp_visual/bubblegum_hands/leftsmack
icon_state = "leftsmack"
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
if(Adjacent(target))
return FALSE
var/list/can_jaunt = get_pools(get_turf(src), 1)
if(!can_jaunt.len)
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination
name = "bubblegum's hallucination"
desc = "Is that really just a hallucination?"
health = 1
maxHealth = 1
alpha = 127.5
crusher_loot = null
loot = null
medal_type = null
score_type = null
deathmessage = "Explodes into a pool of blood!"
death_sound = 'sound/effects/splat.ogg'
true_spawn = FALSE
var/list/pools = get_pools(get_turf(target), 2)
var/list/pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
if(!pools.len)
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Initialize(mapload)
. = ..()
toggle_ai(AI_OFF)
var/obj/effect/temp_visual/decoy/DA = new /obj/effect/temp_visual/decoy(loc, src)
DA.color = "#FF0000"
var/oldtransform = DA.transform
DA.transform = matrix()*2
animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 5)
sleep(5)
qdel(DA)
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/charge(atom/chargeat = target, delay = 3, chargepast = 2)
..()
qdel(src)
var/obj/effect/decal/cleanable/blood/found_bloodpool
pools = get_pools(get_turf(target), 2)
pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
if(pools.len)
shuffle(pools)
found_bloodpool = pick(pools)
if(found_bloodpool)
visible_message("<span class='danger'>[src] sinks into the blood...</span>")
playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1)
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
visible_message("<span class='danger'>And springs back out!</span>")
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Destroy()
new /obj/effect/decal/cleanable/blood(get_turf(src))
. = ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) // hallucinations should not be stopping bubblegum or eachother
return TRUE
return FALSE
return ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
. = list()
for(var/obj/effect/decal/cleanable/nearby in view(T, range))
if(nearby.can_bloodcrawl_in())
. += nearby
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Life()
return
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray()
visible_message("<span class='danger'>[src] sprays a stream of gore!</span>")
var/range = 6 + round(anger_modifier * 0.4)
var/turf/previousturf = get_turf(src)
var/turf/J = previousturf
var/targetdir = get_dir(src, target)
if(target.loc == loc)
targetdir = dir
face_atom(target)
new /obj/effect/decal/cleanable/blood/bubblegum(J)
for(var/i in 1 to range)
J = get_step(previousturf, targetdir)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J))
playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1)
if(!J || !previousturf.CanAtmosPass(J))
break
new /obj/effect/decal/cleanable/blood/bubblegum(J)
previousturf = J
sleep(1)
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/adjustBruteLoss(amount, updating_health = TRUE)
return
/obj/effect/decal/cleanable/blood/bubblegum
amount = 0
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/OpenFire()
return
/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/AttackingTarget()
return
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings()
visible_message("<span class='danger'>[src] summons a shoal of slaughterlings!</span>")
var/max_amount = 6
for(var/H in get_pools(get_turf(src), 1))
if(!max_amount)
break
max_amount--
var/obj/effect/decal/cleanable/blood/B = H
new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(B.loc)
return max_amount
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter
name = "slaughterling"
desc = "Though not yet strong enough to create a true physical form, it's nonetheless determined to murder you."
density = 0
faction = list("mining", "boss")
weather_immunities = list("lava","ash")
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter/CanPass(atom/movable/mover, turf/target, height = 0)
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum))
return 1
return 0
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/try_bloodattack()
return
@@ -1,4 +1,3 @@
/*
COLOSSUS
@@ -31,35 +30,74 @@ Difficulty: Very Hard
attack_sound = 'sound/magic/ratvar_attack.ogg'
icon_state = "eva"
icon_living = "eva"
icon_dead = "dragon_dead"
icon_dead = ""
friendly = "stares down"
icon = 'icons/mob/lavaland/96x96megafauna.dmi'
speak_emote = list("roars")
armour_penetration = 40
melee_damage_lower = 40
melee_damage_upper = 40
speed = 1
speed = 10
move_to_delay = 10
ranged = 1
ranged = TRUE
pixel_x = -32
del_on_death = 1
del_on_death = TRUE
internal_type = /obj/item/gps/internal/colossus
medal_type = BOSS_MEDAL_COLOSSUS
score_type = COLOSSUS_SCORE
crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
loot = list(/obj/structure/closet/crate/necropolis/colossus)
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
deathmessage = "disintegrates, leaving a glowing core in its wake."
death_sound = 'sound/misc/demon_dies.ogg'
attack_action_types = list(/datum/action/innate/megafauna_attack/spiral_attack,
/datum/action/innate/megafauna_attack/aoe_attack,
/datum/action/innate/megafauna_attack/shotgun,
/datum/action/innate/megafauna_attack/alternating_cardinals)
/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/L)
visible_message("<span class='colossus'>[src] disintegrates [L]!</span>")
L.dust()
/datum/action/innate/megafauna_attack/spiral_attack
name = "Spiral Shots"
icon_icon = 'icons/mob/actions/actions.dmi'
button_icon_state = "sniper_zoom"
chosen_message = "<span class='colossus'>You are now firing in a spiral.</span>"
chosen_attack_num = 1
/datum/action/innate/megafauna_attack/aoe_attack
name = "All Directions"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "at_shield2"
chosen_message = "<span class='colossus'>You are now firing in all directions.</span>"
chosen_attack_num = 2
/datum/action/innate/megafauna_attack/shotgun
name = "Shotgun Fire"
icon_icon = 'icons/obj/guns/projectile.dmi'
button_icon_state = "shotgun"
chosen_message = "<span class='colossus'>You are now firing shotgun shots where you aim.</span>"
chosen_attack_num = 3
/datum/action/innate/megafauna_attack/alternating_cardinals
name = "Alternating Shots"
icon_icon = 'icons/obj/guns/projectile.dmi'
button_icon_state = "pistol"
chosen_message = "<span class='colossus'>You are now firing in alternating cardinal directions.</span>"
chosen_attack_num = 4
/mob/living/simple_animal/hostile/megafauna/colossus/OpenFire()
anger_modifier = Clamp(((maxHealth - health)/50),0,20)
ranged_cooldown = world.time + 120
if(client)
switch(chosen_attack)
if(1)
select_spiral_attack()
if(2)
random_shots()
if(3)
blast()
if(4)
alternating_dir_shots()
return
if(enrage(target))
if(move_to_delay == initial(move_to_delay))
visible_message("<span class='colossus'>\"<b>You can't dodge.</b>\"</span>")
@@ -72,26 +110,111 @@ Difficulty: Very Hard
move_to_delay = initial(move_to_delay)
if(prob(20+anger_modifier)) //Major attack
telegraph()
if(health < maxHealth/3)
double_spiral()
else
visible_message("<span class='colossus'>\"<b>Judgement.</b>\"</span>")
spawn(0)
spiral_shoot(rand(0, 1))
select_spiral_attack()
else if(prob(20))
ranged_cooldown = world.time + 30
random_shots()
else
if(prob(70))
ranged_cooldown = world.time + 20
blast()
else
ranged_cooldown = world.time + 40
spawn(0)
alternating_dir_shots()
alternating_dir_shots()
/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.martial_art && prob(H.martial_art.deflection_chance))
. = TRUE
/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots()
ranged_cooldown = world.time + 40
dir_shots(diagonals)
SLEEP_CHECK_DEATH(10)
dir_shots(cardinal)
SLEEP_CHECK_DEATH(10)
dir_shots(diagonals)
SLEEP_CHECK_DEATH(10)
dir_shots(cardinal)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/select_spiral_attack()
telegraph()
if(health < maxHealth/3)
return double_spiral()
visible_message("<span class='colossus'>\"<b>Judgement.</b>\"</span>")
return spiral_shoot()
/mob/living/simple_animal/hostile/megafauna/colossus/proc/double_spiral()
visible_message("<span class='colossus'>\"<b>Die.</b>\"</span>")
SLEEP_CHECK_DEATH(10)
INVOKE_ASYNC(src, .proc/spiral_shoot, FALSE)
INVOKE_ASYNC(src, .proc/spiral_shoot, TRUE)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/spiral_shoot(negative = pick(TRUE, FALSE), counter_start = 8)
var/turf/start_turf = get_step(src, pick(alldirs))
var/counter = counter_start
for(var/i in 1 to 80)
if(negative)
counter--
else
counter++
if(counter > 16)
counter = 1
if(counter < 1)
counter = 16
shoot_projectile(start_turf, counter * 22.5)
playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE)
SLEEP_CHECK_DEATH(1)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/shoot_projectile(turf/marker, set_angle)
if(!isnum(set_angle) && (!marker || marker == loc))
return
var/turf/startloc = get_turf(src)
var/obj/item/projectile/P = new /obj/item/projectile/colossus(startloc)
P.preparePixelProjectile(marker, marker, startloc)
P.firer = src
if(target)
P.original = target
P.fire(set_angle)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/random_shots()
ranged_cooldown = world.time + 30
var/turf/U = get_turf(src)
playsound(U, 'sound/magic/clockwork/invoke_general.ogg', 300, TRUE, 5)
for(var/T in RANGE_TURFS(12, U) - U)
if(prob(5))
shoot_projectile(T)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast(set_angle)
ranged_cooldown = world.time + 20
var/turf/target_turf = get_turf(target)
playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 2)
newtonian_move(get_dir(target_turf, src))
var/angle_to_target = Get_Angle(src, target_turf)
if(isnum(set_angle))
angle_to_target = set_angle
var/static/list/colossus_shotgun_shot_angles = list(12.5, 7.5, 2.5, -2.5, -7.5, -12.5)
for(var/i in colossus_shotgun_shot_angles)
shoot_projectile(target_turf, angle_to_target + i)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/dir_shots(list/dirs)
if(!islist(dirs))
dirs = alldirs.Copy()
playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 2)
for(var/d in dirs)
var/turf/E = get_step(src, d)
shoot_projectile(E)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/telegraph()
for(var/mob/M in range(10,src))
if(M.client)
flash_color(M.client, "#C80000", 1)
shake_camera(M, 4, 3)
playsound(src, 'sound/magic/narsie_attack.ogg', 200, TRUE)
/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/L)
visible_message("<span class='colossus'>[src] disintegrates [L]!</span>")
L.dust()
/obj/effect/temp_visual/at_shield
name = "anti-toolbox field"
@@ -99,15 +222,14 @@ Difficulty: Very Hard
icon = 'icons/effects/effects.dmi'
icon_state = "at_shield2"
layer = FLY_LAYER
luminosity = 2
light_range = 2
duration = 8
var/target
/obj/effect/temp_visual/at_shield/New(new_loc, new_target)
..()
/obj/effect/temp_visual/at_shield/Initialize(mapload, new_target)
. = ..()
target = new_target
spawn(0)
orbit(target, 0, FALSE, 0, 0, FALSE, TRUE)
INVOKE_ASYNC(src, /atom/movable/proc/orbit, target, 0, FALSE, 0, 0, FALSE, TRUE)
/mob/living/simple_animal/hostile/megafauna/colossus/bullet_act(obj/item/projectile/P)
if(!stat)
@@ -117,126 +239,7 @@ Difficulty: Very Hard
var/random_y = rand(0, 72)
AT.pixel_y += random_y
..()
/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.martial_art && prob(H.martial_art.deflection_chance))
. = TRUE
/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots()
dir_shots(diagonals)
sleep(10)
dir_shots(cardinal)
sleep(10)
dir_shots(diagonals)
sleep(10)
dir_shots(cardinal)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/double_spiral()
visible_message("<span class='colossus'>\"<b>Die.</b>\"</span>")
sleep(10)
spawn(0)
spiral_shoot()
spawn(0)
spiral_shoot(1)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/spiral_shoot(negative = 0, counter_start = 1)
var/counter = counter_start
var/turf/marker
for(var/i in 1 to 80)
switch(counter)
if(1)
marker = locate(x, y - 2, z)
if(2)
marker = locate(x - 1, y - 2, z)
if(3)
marker = locate(x - 2, y - 2, z)
if(4)
marker = locate(x - 2, y - 1, z)
if(5)
marker = locate(x - 2, y, z)
if(6)
marker = locate(x - 2, y + 1, z)
if(7)
marker = locate(x - 2, y + 2, z)
if(8)
marker = locate(x - 1, y + 2, z)
if(9)
marker = locate(x, y + 2, z)
if(10)
marker = locate(x + 1, y + 2, z)
if(11)
marker = locate(x + 2, y + 2, z)
if(12)
marker = locate(x + 2, y + 1, z)
if(13)
marker = locate(x + 2, y, z)
if(14)
marker = locate(x + 2, y - 1, z)
if(15)
marker = locate(x + 2, y - 2, z)
if(16)
marker = locate(x + 1, y - 2, z)
if(negative)
counter--
else
counter++
if(counter > 16)
counter = 1
if(counter < 1)
counter = 16
shoot_projectile(marker)
playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 20, 1)
sleep(1)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/shoot_projectile(turf/marker)
if(!marker || marker == loc)
return
var/turf/startloc = get_turf(src)
var/obj/item/projectile/P = new /obj/item/projectile/colossus(startloc)
P.current = startloc
P.starting = startloc
P.firer = src
P.yo = marker.y - startloc.y
P.xo = marker.x - startloc.x
if(target)
P.original = target
else
P.original = marker
P.fire()
/mob/living/simple_animal/hostile/megafauna/colossus/proc/random_shots()
var/turf/U = get_turf(src)
playsound(U, 'sound/magic/invoke_general.ogg', 300, 1, 5)
for(var/T in RANGE_TURFS(12, U) - U)
if(prob(5))
shoot_projectile(T)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast()
playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2)
var/turf/T = get_turf(target)
newtonian_move(get_dir(T, targets_from))
for(var/turf/turf in range(1, T))
shoot_projectile(turf)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/dir_shots(list/dirs)
if(!islist(dirs))
dirs = alldirs.Copy()
playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2)
for(var/d in dirs)
var/turf/E = get_step(src, d)
shoot_projectile(E)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/telegraph()
for(var/mob/M in range(10,src))
if(M.client)
flash_color(M.client, rgb(200, 0, 0), 1)
shake_camera(M, 4, 3)
playsound(get_turf(src),'sound/magic/narsie_attack.ogg', 200, 1)
return ..()
/obj/item/projectile/colossus
name ="death bolt"
@@ -1,3 +1,9 @@
#define DRAKE_SWOOP_HEIGHT 270 //how high up drakes go, in pixels
#define DRAKE_SWOOP_DIRECTION_CHANGE_RANGE 5 //the range our x has to be within to not change the direction we slam from
#define SWOOP_DAMAGEABLE 1
#define SWOOP_INVULNERABLE 2
/*
ASH DRAKE
@@ -6,10 +12,11 @@ Ash drakes spawn randomly wherever a lavaland creature is able to spawn. They ar
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast.
It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs.
The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage.
Whenever possible, the drake will breathe fire directly at it's target, igniting and heavily damaging anything caught in the blast.
It also often causes lava to pool from the ground around you - many nearby turfs will temporarily turn into lava, dealing damage to anything on the turfs.
The drake also utilizes its wings to fly into the sky, flying after its target and attempting to slam down on them. Anything near when it slams down takes huge damage.
- Sometimes it will chain these swooping attacks over and over, making swiftness a necessity.
- Sometimes, it will encase its target in an arena of lava
When an ash drake dies, it leaves behind a chest that can contain four things:
1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power
@@ -39,31 +46,358 @@ Difficulty: Medium
armour_penetration = 40
melee_damage_lower = 40
melee_damage_upper = 40
speed = 1
move_to_delay = 10
ranged = 1
speed = 5
move_to_delay = 5
ranged = TRUE
pixel_x = -16
crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher)
loot = list(/obj/structure/closet/crate/necropolis/dragon)
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
var/swooping = 0
var/swoop_cooldown = 0
var/swooping = NONE
var/player_cooldown = 0
internal_type = /obj/item/gps/internal/dragon
medal_type = BOSS_MEDAL_DRAKE
score_type = DRAKE_SCORE
deathmessage = "collapses into a pile of bones, its flesh sloughing away."
death_sound = 'sound/misc/demon_dies.ogg'
attack_action_types = list(/datum/action/innate/megafauna_attack/fire_cone,
/datum/action/innate/megafauna_attack/fire_cone_meteors,
/datum/action/innate/megafauna_attack/mass_fire,
/datum/action/innate/megafauna_attack/lava_swoop)
/datum/action/innate/megafauna_attack/fire_cone
name = "Fire Cone"
icon_icon = 'icons/obj/wizard.dmi'
button_icon_state = "fireball"
chosen_message = "<span class='colossus'>You are now shooting fire at your target.</span>"
chosen_attack_num = 1
/datum/action/innate/megafauna_attack/fire_cone_meteors
name = "Fire Cone With Meteors"
icon_icon = 'icons/mob/actions/actions.dmi'
button_icon_state = "sniper_zoom"
chosen_message = "<span class='colossus'>You are now shooting fire at your target and raining fire around you.</span>"
chosen_attack_num = 2
/datum/action/innate/megafauna_attack/mass_fire
name = "Mass Fire Attack"
icon_icon = 'icons/effects/fire.dmi'
button_icon_state = "1"
chosen_message = "<span class='colossus'>You are now shooting mass fire at your target.</span>"
chosen_attack_num = 3
/datum/action/innate/megafauna_attack/lava_swoop
name = "Lava Swoop"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "lavastaff_warn"
chosen_message = "<span class='colossus'>You are now swooping and raining lava at your target.</span>"
chosen_attack_num = 4
/obj/item/gps/internal/dragon
icon_state = null
gpstag = "Fiery Signal"
desc = "Here there be dragons."
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
if(swooping)
return
anger_modifier = Clamp(((maxHealth - health)/50),0,20)
ranged_cooldown = world.time + ranged_cooldown_time
if(client)
switch(chosen_attack)
if(1)
fire_cone(meteors = FALSE)
if(2)
fire_cone()
if(3)
mass_fire()
if(4)
lava_swoop()
return
if(prob(15 + anger_modifier))
lava_swoop()
else if(prob(10+anger_modifier))
shoot_fire_attack()
else
fire_cone()
/mob/living/simple_animal/hostile/megafauna/dragon/proc/shoot_fire_attack()
if(health < maxHealth*0.5)
mass_fire()
else
fire_cone()
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain()
if(!target)
return
target.visible_message("<span class='boldwarning'>Fire rains from the sky!</span>")
for(var/turf/turf in range(9,get_turf(target)))
if(prob(11))
new /obj/effect/temp_visual/target(turf)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_pools(var/amount, var/delay = 0.8)
if(!target)
return
target.visible_message("<span class='boldwarning'>Lava starts to pool up around you!</span>")
while(amount > 0)
if(QDELETED(target))
break
var/turf/T = pick(RANGE_TURFS(1, target))
new /obj/effect/temp_visual/lava_warning(T, 60) // longer reset time for the lava
amount--
SLEEP_CHECK_DEATH(delay)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_swoop(var/amount = 30)
if(health < maxHealth * 0.5)
return swoop_attack(lava_arena = TRUE, swoop_cooldown = 60)
INVOKE_ASYNC(src, .proc/lava_pools, amount)
swoop_attack(FALSE, target, 1000) // longer cooldown until it gets reset below
SLEEP_CHECK_DEATH(0)
fire_cone()
if(health < maxHealth*0.5)
SLEEP_CHECK_DEATH(10)
fire_cone()
SLEEP_CHECK_DEATH(10)
fire_cone()
SetRecoveryTime(40)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/mass_fire(var/spiral_count = 12, var/range = 15, var/times = 3)
SLEEP_CHECK_DEATH(0)
for(var/i = 1 to times)
SetRecoveryTime(50)
playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE)
var/increment = 360 / spiral_count
for(var/j = 1 to spiral_count)
var/list/turfs = line_target(j * increment + i * increment / 2, range, src)
INVOKE_ASYNC(src, .proc/fire_line, turfs)
SLEEP_CHECK_DEATH(25)
SetRecoveryTime(30)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_arena()
if(!target)
return
target.visible_message("<span class='boldwarning'>[src] encases you in an arena of fire!</span>")
var/amount = 3
var/turf/center = get_turf(target)
var/list/walled = RANGE_TURFS(3, center) - RANGE_TURFS(2, center)
var/list/drakewalls = list()
for(var/turf/T in walled)
drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free
var/list/indestructible_turfs = list()
for(var/turf/T in RANGE_TURFS(2, center))
if(istype(T, /turf/simulated/floor/indestructible))
continue
if(!istype(T, /turf/simulated/wall/indestructible))
T.ChangeTurf(/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface)
else
indestructible_turfs += T
SLEEP_CHECK_DEATH(10) // give them a bit of time to realize what attack is actually happening
var/list/turfs = RANGE_TURFS(2, center)
while(amount > 0)
var/list/empty = indestructible_turfs.Copy() // can't place safe turfs on turfs that weren't changed to be open
var/any_attack = 0
for(var/turf/T in turfs)
for(var/mob/living/L in T.contents)
if(L.client)
empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield
any_attack = 1
for(var/obj/mecha/M in T.contents)
empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty)
any_attack = 1
if(!any_attack)
for(var/obj/effect/temp_visual/drakewall/D in drakewalls)
qdel(D)
return 0 // nothing to attack in the arena time for enraged attack if we still have a target
for(var/turf/T in turfs)
if(!(T in empty))
new /obj/effect/temp_visual/lava_warning(T)
else if(!istype(T, /turf/simulated/wall/indestructible))
new /obj/effect/temp_visual/lava_safe(T)
amount--
SLEEP_CHECK_DEATH(24)
return 1 // attack finished completely
/mob/living/simple_animal/hostile/megafauna/dragon/proc/arena_escape_enrage() // you ran somehow / teleported away from my arena attack now i'm mad fucker
SLEEP_CHECK_DEATH(0)
SetRecoveryTime(80)
visible_message("<span class='boldwarning'>[src] starts to glow vibrantly as its wounds close up!</span>")
adjustBruteLoss(-250) // yeah you're gonna pay for that, don't run nerd
add_atom_colour(rgb(255, 255, 0), TEMPORARY_COLOUR_PRIORITY)
move_to_delay = move_to_delay / 2
light_range = 10
SLEEP_CHECK_DEATH(10) // run.
mass_fire(20, 15, 3)
move_to_delay = initial(move_to_delay)
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
light_range = initial(light_range)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_cone(var/atom/at = target, var/meteors = TRUE)
playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE)
SLEEP_CHECK_DEATH(0)
if(prob(50) && meteors)
INVOKE_ASYNC(src, .proc/fire_rain)
var/range = 15
var/list/turfs = list()
turfs = line_target(-40, range, at)
INVOKE_ASYNC(src, .proc/fire_line, turfs)
turfs = line_target(0, range, at)
INVOKE_ASYNC(src, .proc/fire_line, turfs)
turfs = line_target(40, range, at)
INVOKE_ASYNC(src, .proc/fire_line, turfs)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/line_target(var/offset, var/range, var/atom/at = target)
if(!at)
return
var/angle = Atan2(at.x - src.x, at.y - src.y) + offset
var/turf/T = get_turf(src)
for(var/i in 1 to range)
var/turf/check = locate(src.x + cos(angle) * i, src.y + sin(angle) * i, src.z)
if(!check)
break
T = check
return (getline(src, T) - get_turf(src))
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_line(var/list/turfs)
SLEEP_CHECK_DEATH(0)
dragon_fire_line(src, turfs)
//fire line keeps going even if dragon is deleted
/proc/dragon_fire_line(var/source, var/list/turfs)
var/list/hit_list = list()
for(var/turf/T in turfs)
if(T.density)
break
new /obj/effect/hotspot(T)
T.hotspot_expose(700,50,1)
for(var/mob/living/L in T.contents)
if(L in hit_list || L == source)
continue
hit_list += L
L.adjustFireLoss(20)
to_chat(L, "<span class='userdanger'>You're hit by [source]'s fire breath!</span>")
// deals damage to mechs
for(var/obj/mecha/M in T.contents)
if(M in hit_list)
continue
hit_list += M
M.take_damage(45, BRUTE, "melee", 1)
sleep(1.5)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(lava_arena = FALSE, atom/movable/manual_target, var/swoop_cooldown = 30)
if(stat || swooping)
return
if(manual_target)
target = manual_target
if(!target)
return
stop_automated_movement = TRUE
swooping |= SWOOP_DAMAGEABLE
density = FALSE
icon_state = "shadow"
visible_message("<span class='boldwarning'>[src] swoops up high!</span>")
var/negative
var/initial_x = x
if(target.x < initial_x) //if the target's x is lower than ours, swoop to the left
negative = TRUE
else if(target.x > initial_x)
negative = FALSE
else if(target.x == initial_x) //if their x is the same, pick a direction
negative = prob(50)
var/obj/effect/temp_visual/dragon_flight/F = new /obj/effect/temp_visual/dragon_flight(loc, negative)
negative = !negative //invert it for the swoop down later
var/oldtransform = transform
alpha = 255
animate(src, alpha = 204, transform = matrix()*0.9, time = 3, easing = BOUNCE_EASING)
for(var/i in 1 to 3)
sleep(1)
if(QDELETED(src) || stat == DEAD) //we got hit and died, rip us
qdel(F)
if(stat == DEAD)
swooping &= ~SWOOP_DAMAGEABLE
animate(src, alpha = 255, transform = oldtransform, time = 0, flags = ANIMATION_END_NOW) //reset immediately
return
animate(src, alpha = 100, transform = matrix()*0.7, time = 7)
swooping |= SWOOP_INVULNERABLE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
SLEEP_CHECK_DEATH(7)
while(target && loc != get_turf(target))
forceMove(get_step(src, get_dir(src, target)))
SLEEP_CHECK_DEATH(0.5)
// Ash drake flies onto its target and rains fire down upon them
var/descentTime = 10
var/lava_success = TRUE
if(lava_arena)
lava_success = lava_arena()
//ensure swoop direction continuity.
if(negative)
if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE))
negative = FALSE
else
if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1))
negative = TRUE
new /obj/effect/temp_visual/dragon_flight/end(loc, negative)
new /obj/effect/temp_visual/dragon_swoop(loc)
animate(src, alpha = 255, transform = oldtransform, descentTime)
SLEEP_CHECK_DEATH(descentTime)
swooping &= ~SWOOP_INVULNERABLE
mouse_opacity = initial(mouse_opacity)
icon_state = "dragon"
playsound(loc, 'sound/effects/meteorimpact.ogg', 200, TRUE)
for(var/mob/living/L in orange(1, src))
if(L.stat)
visible_message("<span class='warning'>[src] slams down on [L], crushing [L.p_them()]!</span>")
L.gib()
else
L.adjustBruteLoss(75)
if(L && !QDELETED(L)) // Some mobs are deleted on death
var/throw_dir = get_dir(src, L)
if(L.loc == loc)
throw_dir = pick(alldirs)
var/throwtarget = get_edge_target_turf(src, throw_dir)
L.throw_at(throwtarget, 3)
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
for(var/obj/mecha/M in orange(1, src))
M.take_damage(75, BRUTE, "melee", 1)
for(var/mob/M in range(7, src))
shake_camera(M, 15, 1)
density = TRUE
SLEEP_CHECK_DEATH(1)
swooping &= ~SWOOP_DAMAGEABLE
SetRecoveryTime(swoop_cooldown)
if(!lava_success)
arena_escape_enrage()
/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target)
if(severity == 3)
if(severity == EXPLODE_LIGHT)
return
..()
/mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount, updating_health = TRUE)
if(swooping)
if(swooping & SWOOP_INVULNERABLE)
return FALSE
return ..()
/mob/living/simple_animal/hostile/megafauna/dragon/visible_message()
if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit
return
return ..()
/mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget()
if(!swooping)
return ..()
@@ -83,181 +417,161 @@ Difficulty: Medium
/mob/living/simple_animal/hostile/megafauna/dragon/Process_Spacemove(movement_dir = 0)
return 1
/obj/effect/temp_visual/fireball
icon = 'icons/obj/wizard.dmi'
icon_state = "fireball"
name = "fireball"
desc = "Get out of the way!"
layer = 6
randomdir = 0
duration = 12
pixel_z = 500
/obj/effect/temp_visual/lava_warning
icon_state = "lavastaff_warn"
layer = BELOW_MOB_LAYER
light_range = 2
duration = 13
/obj/effect/temp_visual/fireball/New(loc)
..()
animate(src, pixel_z = 0, time = 12)
/obj/effect/temp_visual/lava_warning/ex_act()
return
/obj/effect/temp_visual/target
icon = 'icons/mob/actions/actions.dmi'
icon_state = "sniper_zoom"
layer = MOB_LAYER - 0.1
luminosity = 2
duration = 12
/obj/effect/temp_visual/lava_warning/Initialize(mapload, var/reset_time = 10)
. = ..()
INVOKE_ASYNC(src, .proc/fall, reset_time)
src.alpha = 63.75
animate(src, alpha = 255, time = duration)
/obj/effect/temp_visual/lava_warning/proc/fall(var/reset_time)
var/turf/T = get_turf(src)
playsound(T,'sound/magic/fleshtostone.ogg', 80, TRUE)
sleep(duration)
playsound(T,'sound/magic/fireball.ogg', 200, TRUE)
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon))
continue
L.adjustFireLoss(10)
to_chat(L, "<span class='userdanger'>You fall directly into the pool of lava!</span>")
// deals damage to mechs
for(var/obj/mecha/M in T.contents)
M.take_damage(45, BRUTE, "melee", 1)
// changes turf to lava temporarily
if(!T.density && !istype(T, /turf/simulated/floor/plating/lava))
var/lava_turf = /turf/simulated/floor/plating/lava/smooth
var/reset_turf = T.type
T.ChangeTurf(lava_turf)
sleep(reset_time)
T.ChangeTurf(reset_turf)
/obj/effect/temp_visual/drakewall
desc = "An ash drakes true flame."
name = "Fire Barrier"
icon = 'icons/effects/fire.dmi'
icon_state = "1"
anchored = TRUE
opacity = 0
density = TRUE
duration = 82
color = COLOR_DARK_ORANGE
/obj/effect/temp_visual/drakewall/CanAtmosPass()
return !density
/obj/effect/temp_visual/lava_safe
icon = 'icons/obj/hand_of_god_structures.dmi'
icon_state = "trap-earth"
layer = BELOW_MOB_LAYER
light_range = 2
duration = 13
/obj/effect/temp_visual/dragon_swoop
name = "certain death"
desc = "Don't just stand there, move!"
icon = 'icons/effects/96x96.dmi'
icon_state = "landing"
layer = MOB_LAYER - 0.1
layer = BELOW_MOB_LAYER
pixel_x = -32
pixel_y = -32
color = "#FF0000"
duration = 10
/obj/effect/temp_visual/dragon_flight
icon = 'icons/mob/lavaland/64x64megafauna.dmi'
icon_state = "dragon"
layer = ABOVE_ALL_MOB_LAYER
pixel_x = -16
duration = 10
randomdir = FALSE
/obj/effect/temp_visual/dragon_flight/Initialize(mapload, negative)
. = ..()
INVOKE_ASYNC(src, .proc/flight, negative)
/obj/effect/temp_visual/dragon_flight/proc/flight(negative)
if(negative)
animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT*0.1, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING)
else
animate(src, pixel_x = DRAKE_SWOOP_HEIGHT*0.1, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING)
sleep(3)
icon_state = "swoop"
if(negative)
animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7)
else
animate(src, pixel_x = DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7)
/obj/effect/temp_visual/dragon_flight/end
pixel_x = DRAKE_SWOOP_HEIGHT
pixel_z = DRAKE_SWOOP_HEIGHT
duration = 10
/obj/effect/temp_visual/dragon_flight/end/flight(negative)
if(negative)
pixel_x = -DRAKE_SWOOP_HEIGHT
animate(src, pixel_x = -16, pixel_z = 0, time = 5)
else
animate(src, pixel_x = -16, pixel_z = 0, time = 5)
obj/effect/temp_visual/fireball
icon = 'icons/obj/wizard.dmi'
icon_state = "fireball"
name = "fireball"
desc = "Get out of the way!"
layer = FLY_LAYER
randomdir = FALSE
duration = 9
pixel_z = 270
/obj/effect/temp_visual/fireball/Initialize()
. = ..()
animate(src, pixel_z = 0, time = duration)
/obj/effect/temp_visual/target
icon = 'icons/mob/actions/actions.dmi'
icon_state = "sniper_zoom"
layer = BELOW_MOB_LAYER
light_range = 2
duration = 9
/obj/effect/temp_visual/target/ex_act()
return
/obj/effect/temp_visual/target/New(loc)
..()
spawn(0)
fall()
/obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit)
. = ..()
INVOKE_ASYNC(src, .proc/fall, flame_hit)
/obj/effect/temp_visual/target/proc/fall()
/obj/effect/temp_visual/target/proc/fall(list/flame_hit)
var/turf/T = get_turf(src)
playsound(T,'sound/magic/fireball.ogg', 200, 1)
playsound(T,'sound/magic/fleshtostone.ogg', 80, TRUE)
new /obj/effect/temp_visual/fireball(T)
sleep(12)
explosion(T, 0, 0, 1, 0, 0, 0, 1, 1)
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
anger_modifier = Clamp(((maxHealth - health)/50),0,20)
ranged_cooldown = world.time + ranged_cooldown_time
if(swooping)
fire_rain()
return
if(prob(15 + anger_modifier) && !client)
if(health < maxHealth/2)
spawn(0)
swoop_attack(1)
else
fire_rain()
else if(prob(10+anger_modifier) && !client)
if(health > maxHealth/2)
spawn(0)
swoop_attack(0)
else
spawn(0)
triple_swoop(0)
else
fire_walls()
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain()
visible_message("<span class='boldwarning'>Fire rains from the sky!</span>")
for(var/turf/turf in range(12,get_turf(src)))
if(prob(10))
new /obj/effect/temp_visual/target(turf)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls()
playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1)
for(var/d in cardinal)
spawn(0)
fire_wall(d)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir)
var/list/hit_things = list(src)
var/turf/E = get_edge_target_turf(src, dir)
var/range = 10
var/turf/previousturf = get_turf(src)
for(var/turf/J in getline(src,E))
if(!range || !previousturf.CanAtmosPass(J))
break
range--
new /obj/effect/hotspot(J)
J.hotspot_expose(700,50,1)
for(var/mob/living/L in J.contents - hit_things)
L.adjustFireLoss(20)
sleep(duration)
if(ismineralturf(T))
var/turf/simulated/mineral/M = T
M.gets_drilled()
playsound(T, "explosion", 80, TRUE)
new /obj/effect/hotspot(T)
T.hotspot_expose(700, 50, 1)
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon))
continue
if(islist(flame_hit) && !flame_hit[L])
L.adjustFireLoss(40)
to_chat(L, "<span class='userdanger'>You're hit by the drake's fire breath!</span>")
hit_things += L
previousturf = J
sleep(1)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop()
swoop_attack()
swoop_attack()
swoop_attack()
/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target)
if(stat || swooping)
return
swoop_cooldown = world.time + 200
var/atom/swoop_target
if(manual_target)
swoop_target = manual_target
else
swoop_target = target
stop_automated_movement = TRUE
swooping = 1
density = 0
icon_state = "swoop"
visible_message("<span class='boldwarning'>[src] swoops up high!</span>")
if(prob(50))
animate(src, pixel_x = 500, pixel_z = 500, time = 10)
else
animate(src, pixel_x = -500, pixel_z = 500, time = 10)
sleep(30)
var/turf/tturf
if(fire_rain)
fire_rain()
icon_state = "dragon"
if(swoop_target && !QDELETED(swoop_target) && swoop_target.z == src.z)
tturf = get_turf(swoop_target)
else
tturf = get_turf(src)
forceMove(tturf)
new /obj/effect/temp_visual/dragon_swoop(tturf)
animate(src, pixel_x = initial(pixel_x), pixel_z = 0, time = 10)
sleep(10)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1)
for(var/mob/living/L in orange(1, src))
if(L.stat)
visible_message("<span class='warning'>[src] slams down on [L], crushing [L.p_them()]!</span>")
L.gib()
flame_hit[L] = TRUE
else
L.adjustBruteLoss(75)
if(L && !QDELETED(L)) // Some mobs are deleted on death
var/throw_dir = get_dir(src, L)
if(L.loc == loc)
throw_dir = pick(alldirs)
var/throwtarget = get_edge_target_turf(src, throw_dir)
L.throw_at(throwtarget, 3)
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
for(var/mob/M in range(7, src))
shake_camera(M, 15, 1)
stop_automated_movement = FALSE
swooping = 0
density = 1
/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A)
if(!istype(A))
return
if(swoop_cooldown >= world.time)
to_chat(src, "<span class='warning'>You need to wait 20 seconds between swoop attacks!</span>")
return
swoop_attack(1, A)
/obj/item/gps/internal/dragon
icon_state = null
gpstag = "Fiery Signal"
desc = "Here there be dragons."
invisibility = 100
L.adjustFireLoss(10) //if we've already hit them, do way less damage
/mob/living/simple_animal/hostile/megafauna/dragon/lesser
name = "lesser ash drake"
@@ -267,9 +581,92 @@ Difficulty: Medium
obj_damage = 80
melee_damage_upper = 30
melee_damage_lower = 30
mouse_opacity = MOUSE_OPACITY_ICON
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
loot = list()
crusher_loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
attack_action_types = list()
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/AltClickOn(atom/movable/A)
if(!istype(A))
return
if(player_cooldown >= world.time)
to_chat(src, "<span class='warning'>You need to wait [(player_cooldown - world.time) / 10] seconds before swooping again!</span>")
return
swoop_attack(FALSE, A)
lava_pools(10, 2) // less pools but longer delay before spawns
player_cooldown = world.time + 200 // needs seperate cooldown or cant use fire attacks
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
return
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon
name = "space dragon"
maxHealth = 250
health = 250
faction = list("neutral")
desc = "A space carp turned dragon by vile magic. Has the same ferocity of a space carp, but also a much more enabling body."
icon = 'icons/mob/spacedragon.dmi'
icon_state = "spacedragon"
icon_living = "spacedragon"
icon_dead = "spacedragon_dead"
obj_damage = 80
melee_damage_upper = 35
melee_damage_lower = 35
speed = 0
mouse_opacity = MOUSE_OPACITY_ICON
loot = list()
crusher_loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
move_force = MOVE_FORCE_NORMAL
move_resist = MOVE_FORCE_NORMAL
pull_force = MOVE_FORCE_NORMAL
deathmessage = "screeches as its wings turn to dust and it collapses on the floor, life estinguished."
attack_action_types = list()
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/grant_achievement(medaltype, scoretype)
return
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/Initialize(mapload)
var/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon/repulse_action = new /obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon(src)
repulse_action.action.Grant(src)
mob_spell_list += repulse_action
. = ..()
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/proc/fire_stream(var/atom/at = target)
playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE)
SLEEP_CHECK_DEATH(0)
var/range = 20
var/list/turfs = list()
turfs = line_target(0, range, at)
INVOKE_ASYNC(src, .proc/fire_line, turfs)
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/OpenFire()
if(swooping)
return
ranged_cooldown = world.time + ranged_cooldown_time
fire_stream()
/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon
name = "Tail Sweep"
desc = "Throw back attackers with a sweep of your tail."
sound = 'sound/magic/tail_swing.ogg'
charge_max = 150
clothes_req = FALSE
range = 1
cooldown_min = 150
invocation_type = "none"
sparkle_path = /obj/effect/temp_visual/dir_setting/tailsweep
action_icon_state = "tailsweep"
action_background_icon_state = "bg_alien"
/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon/cast(list/targets, mob/user = usr)
if(iscarbon(user))
var/mob/living/carbon/C = user
playsound(C.loc, 'sound/effects/hit_punch.ogg', 80, TRUE, TRUE)
C.spin(6, 1)
..(targets, user, 3)
/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/AltClickOn(atom/movable/A)
return
File diff suppressed because it is too large Load Diff
@@ -7,11 +7,11 @@
sentience_type = SENTIENCE_BOSS
environment_smash = ENVIRONMENT_SMASH_RWALLS
obj_damage = 400
luminosity = 3
light_range = 3
faction = list("mining", "boss")
weather_immunities = list("lava","ash")
flying = 1
robust_searching = 1
flying = TRUE
robust_searching = TRUE
ranged_ignores_vision = TRUE
stat_attack = DEAD
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
@@ -20,6 +20,12 @@
maxbodytemp = INFINITY
vision_range = 5
aggro_vision_range = 18
move_force = MOVE_FORCE_OVERPOWERING
move_resist = MOVE_FORCE_OVERPOWERING
pull_force = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_LARGE
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
var/list/crusher_loot
var/medal_type
var/score_type = BOSS_SCORE
@@ -27,13 +33,9 @@
var/anger_modifier = 0
var/obj/item/gps/internal_gps
var/internal_type
move_force = MOVE_FORCE_OVERPOWERING
move_resist = MOVE_FORCE_OVERPOWERING
pull_force = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_LARGE
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
var/recovery_time = 0
var/true_spawn = TRUE // if this is a megafauna that should grant achievements, or have a gps signal
var/nest_range = 10
var/chosen_attack = 1 // chosen attack num
var/list/attack_action_types = list()
@@ -50,6 +52,16 @@
QDEL_NULL(internal_gps)
return ..()
/mob/living/simple_animal/hostile/megafauna/Moved()
if(nest && nest.parent && get_dist(nest.parent, src) > nest_range)
var/turf/closest = get_turf(nest.parent)
for(var/i = 1 to nest_range)
closest = get_step(closest, get_dir(closest, src))
forceMove(closest) // someone teleported out probably and the megafauna kept chasing them
target = null
return
return ..()
/mob/living/simple_animal/hostile/megafauna/can_die()
return ..() && health <= 0
@@ -68,6 +80,8 @@
loot = crusher_loot
/mob/living/simple_animal/hostile/megafauna/AttackingTarget()
if(recovery_time >= world.time)
return
. = ..()
if(. && isliving(target))
var/mob/living/L = target
@@ -90,13 +104,14 @@
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
if(!L)
return
return FALSE
visible_message(
"<span class='danger'>[src] devours [L]!</span>",
"<span class='userdanger'>You feast on [L], restoring your health!</span>")
if(!is_station_level(z) && !client) //NPC monsters won't heal while on station
if(!is_station_level(z) || client) //NPC monsters won't heal while on station
adjustBruteLoss(-L.maxHealth/2)
L.gib()
return TRUE
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target)
switch(severity)
@@ -109,6 +124,10 @@
if(3)
adjustBruteLoss(50)
/mob/living/simple_animal/hostile/megafauna/proc/SetRecoveryTime(buffer_time)
recovery_time = world.time + buffer_time
ranged_cooldown = world.time + buffer_time
/mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype, scoretype, crusher_kill)
if(!medal_type || admin_spawned || !SSmedals.hub_enabled) //Don't award medals if the medal type isn't set
return FALSE
@@ -336,6 +336,31 @@
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
return ..()
/datum/reagent/consumable/garlic
name = "Garlic Juice"
id = "garlic"
description = "Crushed garlic. Chefs love it, but it can make you smell bad."
color = "#FEFEFE"
taste_description = "garlic"
metabolization_rate = 0.15 * REAGENTS_METABOLISM
/datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/M)
var/update_flags = STATUS_UPDATE_NONE
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.vampire && !H.mind.vampire.get_ability(/datum/vampire_passive/full)) //incapacitating but not lethal.
if(prob(min(25, current_cycle)))
to_chat(H, "<span class='danger'>You can't get the scent of garlic out of your nose! You can barely think...</span>")
H.Weaken(1)
H.Jitter(10)
H.fakevomit()
else
if(H.job == "Chef")
if(prob(20)) //stays in the system much longer than sprinkles/banana juice, so heals slower to partially compensate
update_flags |= H.adjustBruteLoss(-1, FALSE)
update_flags |= H.adjustFireLoss(-1, FALSE)
return ..() | update_flags
/datum/reagent/consumable/sprinkles
name = "Sprinkles"
id = "sprinkles"
@@ -941,7 +966,7 @@
id = "entpoly"
description = "An ichor, derived from a certain mushroom, makes for a bad time."
color = "#1d043d"
taste_description = "mold"
taste_description = "bitter mushroom"
/datum/reagent/consumable/entpoly/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -960,13 +985,13 @@
id = "tinlux"
description = "A stimulating ichor which causes luminescent fungi to grow on the skin. "
color = "#b5a213"
var/light_activated = 0
taste_description = "mold"
var/light_activated = FALSE
taste_description = "tingling mushroom"
/datum/reagent/consumable/tinlux/on_mob_life(mob/living/M)
if(!light_activated)
M.set_light(2)
light_activated = 1
light_activated = TRUE
return ..()
/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M)
@@ -978,11 +1003,11 @@
description = "A bubbly paste that heals wounds of the skin."
color = "#d3a308"
nutriment_factor = 3 * REAGENTS_METABOLISM
taste_description = "sweetness"
taste_description = "fruity mushroom"
/datum/reagent/consumable/vitfro/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
if(prob(80))
update_flags |= M.adjustBruteLoss(-1 * REAGENTS_EFFECT_MULTIPLIER, FALSE)
update_flags |= M.adjustFireLoss(-1 * REAGENTS_EFFECT_MULTIPLIER, FALSE)
return ..() | update_flags
return ..() | update_flags
@@ -82,12 +82,12 @@
/obj/item/reagent_containers/hypospray/combat
name = "combat stimulant injector"
desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat."
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(10)
amount_per_transfer_from_this = 15
possible_transfer_amounts = list(15)
icon_state = "combat_hypo"
volume = 75
volume = 90
ignore_flags = 1 // So they can heal their comrades.
list_reagents = list("epinephrine" = 30, "omnizine" = 30, "teporone" = 15)
list_reagents = list("epinephrine" = 30, "weak_omnizine" = 30, "salglu_solution" = 30)
/obj/item/reagent_containers/hypospray/combat/nanites
desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with expensive medical nanites for rapid healing."
@@ -28,8 +28,8 @@
list_reagents = list("silver_sulfadiazine" = 40)
/obj/item/reagent_containers/food/pill/patch/synthflesh
name = "syntheflesh patch"
desc = "Helps with burn injuries."
name = "synthflesh patch"
desc = "Helps with brute and burn injuries."
icon_state = "bandaid_med"
instant_application = 1
list_reagents = list("synthflesh" = 20)
+3
View File
@@ -10,6 +10,9 @@
/mob/proc/get_int_organ_tag(tag) //is it a brain, is it a brain_tumor?
return
/mob/living/proc/get_organ(zone)
return
/mob/living/carbon/get_int_organ(typepath)
return (locate(typepath) in internal_organs)
+5
View File
@@ -439,6 +439,8 @@ HIGH_POP_MC_MODE_AMOUNT 65
##Disengage high pop mode if player count drops below this
DISABLE_HIGH_POP_MC_MODE_AMOUNT 60
##Developer options
##Uncomment to enable developer start. Auto starts the server after initialization
##DEVELOPER_EXPRESS_START
@@ -447,3 +449,6 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60
## Uncomment to give a confirmation before hitting start now
#START_NOW_CONFIRMATION
## If uncommented, all gamemodes will respect the number of required players. Defaults to no.
#ENABLE_GAMEMODE_PLAYER_LIMIT
@@ -404,8 +404,8 @@ h1.alert, h2.alert {color: #FFF;}
/* MEGAFAUNA */
.colossus {color: #7F282A; font-size: 175%;}
.hierophant {color: #660099; font-weight: bold; font-size: 150%;}
.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;}
.hierophant {color: #660099; font-weight: bold; font-style: italic;}
.hierophant_warning {color: #660099; font-style: italic;}
/* EMOJI STUFF */
.emoji {max-height: 16px; max-width: 16px}
+2 -2
View File
@@ -401,8 +401,8 @@ h1.alert, h2.alert {color: #000000;}
/* MEGAFAUNA */
.colossus {color: #7F282A; font-size: 175%;}
.hierophant {color: #660099; font-weight: bold; font-size: 150%;}
.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;}
.hierophant {color: #660099; font-weight: bold; font-style: italic;}
.hierophant_warning {color: #660099; font-style: italic;}
/* EMOJI STUFF */
.emoji {max-height: 16px; max-width: 16px}
@@ -0,0 +1,4 @@
author: "variableundefined"
delete-after: True
changes:
- rscadd: "Config option to let gamemode ignore the number of required players."
@@ -0,0 +1,4 @@
author: "variableundefined"
delete-after: True
changes:
- tweak: "Contribution guideline has been updated. No in game changes."
@@ -0,0 +1,9 @@
author: "Fox McCloud"
delete-after: True
changes:
- tweak: "Updates moonflower, sunflower, novaflower, and pineapple sprites"
- rscadd: "Adds in Garlic"
- bugfix: "Fixes a few issues with incorrect values from the wine PR"
- rscadd: "Can now grow and extract the reagents/traits of Lavaland flora"
- tweak: "Slightly tweaks soybean oil production on soybeans"
- rscadd: "Adds amusing garlic suicide"
@@ -0,0 +1,4 @@
author: "variableundefined"
delete-after: True
changes:
- tweak: "Github pull request template has been changed"
@@ -0,0 +1,8 @@
author: "Fox McCloud"
delete-after: True
changes:
- rscadd: "Ash Drake reworked; it's much more powerful now and has a diverse set of attacks--its fire breath is more random, it moves faster, it can turn the ground into lava, and once it's lower on health, will seal you into an arena and make you play the \"only one turf is safe; stand on it or suffer\" mini-game"
- rscadd: "Bubblegum is now much more difficult; instead of just spraying blood at you and attempting to endlessly charge you (walking backwards essentially counters it), it's now faster, engages in zig-zag attacks, uses a hallucination multi-attack, and can rapidly melee attack you in range"
- bugfix: "Fixes megafauana endlessly attacking dead mobs"
- tweak: "Blood drunk Colossus, and Ash Drake made to be more player friendly if they control the fauna"
- rscadd: "Adds in Space dragon; a very weak version of the Ash drake which can't swoop, but can still breathe fire--has a spell that whips you back with its tail, too (not currently used anywhere)"
@@ -0,0 +1,9 @@
author: "AzuleUtama"
delete-after: True
changes:
- rscdel: "Sarin gas grenades no longer purchasable for nuke ops.
balance: Grenadier belt now contains a sarin gas grenade.
balance: Tactical medkit's hypospray tweaked to contain chems better for dealing with newcrit.
balance: C20 bundle increased in price to 18TC, contains an additional clip of ammo.
balance: Medical bundle increased in price to 20TC, Donk LMG removed, replaced with medbeam gun and magboots."
- spellcheck: "Fixed some minor spelling/grammar errors with synthflesh patches and sarin gas grenades."
@@ -0,0 +1,4 @@
author: "Fox McCloud"
delete-after: True
changes:
- tweak: "The real Roman shield and real Roman helmets in the Autodrobe have been replaced by fake, armorless, varieties"
@@ -0,0 +1,4 @@
author: "Shadow-Quill"
delete-after: True
changes:
- tweak: "Blobs now get a audio notification roundstart (like traitors do.)"
@@ -0,0 +1,4 @@
author: "Dave-TH"
delete-after: True
changes:
- bugfix: "Fixes some vending machines (namely miner nanomeds) from adding all of their product twice."
@@ -0,0 +1,4 @@
author: "Couls"
delete-after: True
changes:
- bugfix: "hotkey menu option in the dropdown works correctly now"
@@ -0,0 +1,4 @@
author: "TDSSS"
delete-after: True
changes:
- tweak: "lowered attack log level of self-harm"
@@ -0,0 +1,4 @@
author: "AzuleUtama"
delete-after: True
changes:
- bugfix: "R&D Console no longer has a default design called 'Name' show up in the mining category."
@@ -0,0 +1,4 @@
author: "Ty-Omaha"
delete-after: True
changes:
- bugfix: "SSD players no longer drown in shallow water"
@@ -0,0 +1,6 @@
author: "Fox McCloud"
delete-after: True
changes:
- rscadd: "Hierophant has been updated--it'll be a bit tougher and will attempt to trap you if you run for it."
- tweak: "Heirophant is no longer a weird bird thing, but a massive, indecipherable piece of machinery that will make you dance to ITS tune"
- tweak: "Hierophant club is weaker up front, but becomes stronger the lower health you are"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 949 B

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More