diff --git a/ModularTegustation/Teguicons/128x128.dmi b/ModularTegustation/Teguicons/128x128.dmi index e579a2c21810..35930cadc906 100644 Binary files a/ModularTegustation/Teguicons/128x128.dmi and b/ModularTegustation/Teguicons/128x128.dmi differ diff --git a/ModularTegustation/Teguicons/abno_cores/aleph.dmi b/ModularTegustation/Teguicons/abno_cores/aleph.dmi index 30c5e462f106..db99b3db1fc7 100644 Binary files a/ModularTegustation/Teguicons/abno_cores/aleph.dmi and b/ModularTegustation/Teguicons/abno_cores/aleph.dmi differ diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 0a29f47ae96a..84fd62ed8398 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -1102,3 +1102,25 @@ icon = 'icons/obj/manager_bullets.dmi' icon_state = "execution" duration = 10 + +/obj/effect/temp_visual/tile_broken + name = "damaged floor" + icon = 'icons/turf/floors.dmi' + icon_state = "platingdmg3" + layer = TURF_LAYER + density = FALSE + duration = 8 SECONDS + +/obj/effect/temp_visual/tile_broken/Initialize() + . = ..() + addtimer(CALLBACK(src, PROC_REF(FadeOut)), 6 SECONDS) + +/obj/effect/temp_visual/tile_broken/proc/FadeOut() + animate(src, alpha = 0, time = 2 SECONDS) + +/obj/effect/temp_visual/tile_broken/type_2 + icon_state = "damaged5" + +/obj/effect/temp_visual/tile_broken/type_3 + icon_state = "damaged3" + layer = ABOVE_NORMAL_TURF_LAYER diff --git a/code/modules/mob/living/simple_animal/abnormality/abno_cores.dm b/code/modules/mob/living/simple_animal/abnormality/abno_cores.dm index ce9cc2fe30be..3338aef93089 100644 --- a/code/modules/mob/living/simple_animal/abnormality/abno_cores.dm +++ b/code/modules/mob/living/simple_animal/abnormality/abno_cores.dm @@ -69,7 +69,44 @@ /obj/machinery/abno_core_extractor name = "abnormality core containment unit" - desc = "A device used to transfer abnormalities into containment cells." + desc = "A device used to transfer abnormality cores into containment cells." icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" density = FALSE + +/obj/item/abno_core_key + name = "enkephalin agitation matrix" + desc = "A single-use gadget used to transfer abnormality cores into containment cells." + icon = 'ModularTegustation/Teguicons/teguitems.dmi' + icon_state = "key_active" + +/obj/item/abno_core_key/pre_attack(atom/A, mob/living/user, params) + . = ..() + if(istype(A, /obj/structure/abno_core)) + var/obj/structure/abno_core/target = A + user.playsound_local(user, 'sound/machines/terminal_prompt.ogg', 50, FALSE) + var/response = alert(user,"Will you really extract [A]?","This cannot be reversed.","Yes","No") + if(response == "Yes" && do_after(user, 10, A)) + qdel(src) + target.Extract() + to_chat(user, span_nicegreen("[src] succesfully applied!")) + return + to_chat(user, "You decide not to extract [A].") + user.playsound_local(user, 'sound/machines/terminal_error.ogg', 50, FALSE) + +/obj/effect/temp_visual/abnocore_spiral + icon = 'icons/effects/96x96.dmi' + icon_state = "clockwork_gateway_active" + layer = ABOVE_NORMAL_TURF_LAYER + pixel_x = -32 + base_pixel_x = -32 + pixel_y = -32 + base_pixel_y = -32 + color = "#8F00FF" + duration = 2 SECONDS + +/obj/effect/temp_visual/abnocore_spiral/Initialize() + . = ..() + var/matrix/M = matrix() + M *= 0.1 + animate(src, alpha = 0, transform = M, time = (duration - 5)) diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/giant.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/giant.dm new file mode 100644 index 000000000000..f1a90a93e1c4 --- /dev/null +++ b/code/modules/mob/living/simple_animal/abnormality/aleph/giant.dm @@ -0,0 +1,294 @@ +/mob/living/simple_animal/hostile/abnormality/giant + name = "The Giant Atop the Beanstalk" + desc = "A hunchbacked, sweaty man. Easily over 20 feet tall." + icon = 'ModularTegustation/Teguicons/128x128.dmi' + icon_state = "giant" + icon_living = "giant" + icon_dead = "giant" + core_icon = "giant" + portrait = "beanstalk" + pixel_x = -48 + base_pixel_x = -48 + speak_emote = list("bellows") + attack_verb_continuous = "attacks" + attack_verb_simple = "attack" + attack_sound = 'sound/abnormalities/mountain/slam.ogg' + /* Stats */ + threat_level = ALEPH_LEVEL + health = 3500 + maxHealth = 3500 + damage_coeff = list(RED_DAMAGE = 0.2, WHITE_DAMAGE = 1.2, BLACK_DAMAGE = 0.6, PALE_DAMAGE = 1.2) + melee_damage_type = RED_DAMAGE + melee_damage_lower = 80 + melee_damage_upper = 100 + move_to_delay = 5 + casingtype = /obj/item/ammo_casing/caseless/giant + projectilesound = 'sound/weapons/fixer/reverb_grand_dash.ogg' + ranged = TRUE + /* Works */ + start_qliphoth = 2 + can_breach = TRUE + del_on_death = FALSE + work_chances = list( + ABNORMALITY_WORK_INSTINCT = list(25, 30, 30, 50, 50), + ABNORMALITY_WORK_INSIGHT = 0, + ABNORMALITY_WORK_ATTACHMENT = 20, + ABNORMALITY_WORK_REPRESSION = list(0, 0, 40, 45, 50), + ) + max_boxes = 32 + work_damage_amount = 14 + work_damage_type = RED_DAMAGE + + ego_list = list( + /datum/ego_datum/weapon/giant,//this is the TETH one + /datum/ego_datum/armor/giant, + ) + + gift_type = /datum/ego_gifts/giant//FIXME:this is the one you get from beanstalk + gift_message = "You find the giant's treasure!" + abnormality_origin = ABNORMALITY_ORIGIN_ORIGINAL + + can_spawn = FALSE//This is a secret abnormality. You can only spawn it via special means + + observation_prompt = "The giant sits in his cell, brushing the hair of his wife's severed head.
\ + You can only imagine how she was reduced to such a miserable state.
\ + Across the room, you see the goose that laid golden eggs." + observation_choices = list("Steal the Giant's treasure.", "Don't enter") + correct_choices = list("Steal the Giant's treasure.") + observation_success_message = "You manage to steal the giant's treasure, at your own peril.
\ + It would be best to avoid this abnormality for the time being." + observation_fail_message = "The bored giant picks his nose. It would be fruitless to provoke him." + + var/jump_cooldown = 0 + var/jump_cooldown_time = 25 SECONDS + var/can_act = TRUE + var/stomping = FALSE + +/mob/living/simple_animal/hostile/abnormality/giant/AttackingTarget() + if(!can_act) + return FALSE + if(prob(35) && (!client)) + return TryJump()//put the grab here instead + return Ground_Smack() + +/mob/living/simple_animal/hostile/abnormality/giant/OpenFire() + if(!can_act) + return FALSE + if(prob(35) && !client) + return Ground_Smack()//TODO: make a "hello" styled version of this. It only works in cardinal directions + ..() + +/mob/living/simple_animal/hostile/abnormality/giant/Move() + if(!can_act) + return FALSE + ..() + +/mob/living/simple_animal/hostile/abnormality/giant/Moved() + . = ..() + playsound(get_turf(src), 'sound/abnormalities/doomsdaycalendar/Doomsday_Attack.ogg', 50, 0, 3) + for(var/mob/living/M in livinginrange(20, get_turf(src))) + shake_camera(M, 1, 1) + if(!stomping) + return + var/list/been_hit = list() + var/stomp_damage = melee_damage_upper / 10 + for(var/turf/T in view(2)) + new /obj/effect/temp_visual/smash_effect(T) + been_hit = HurtInTurf(T, been_hit, stomp_damage, RED_DAMAGE, null, TRUE, FALSE, TRUE, hurt_structure = TRUE) + +/mob/living/simple_animal/hostile/abnormality/giant/Life() + . = ..() + if(IsContained()) // Contained + return + if(!can_act) + return + if(.) + if(client) + return + if(jump_cooldown <= world.time) + INVOKE_ASYNC(src, PROC_REF(TryJump)) + return + +/mob/living/simple_animal/hostile/abnormality/giant/death() + new /obj/effect/temp_visual/abnocore_spiral(get_turf(src)) + icon = 'ModularTegustation/Teguicons/abno_cores/aleph.dmi' + pixel_x = -16 + base_pixel_x = -16 + density = FALSE + animate(src, alpha = 0, time = 5 SECONDS) + QDEL_IN(src, 5 SECONDS) + ..() + +/mob/living/simple_animal/hostile/abnormality/giant/CreateAbnoCore(name, core_icon)//This is how you're supposed to place it in the facility. + var/obj/structure/abno_core/C = new(get_turf(src))//some duplicate code because I need a reference to C + C.name = initial(name) + " Core" + C.desc = "The core of [initial(name)]" + C.icon_state = core_icon + C.contained_abno = src.type + C.threat_level = threat_level + C.icon = 'ModularTegustation/Teguicons/abno_cores/aleph.dmi' + new /obj/item/abno_core_key(get_turf(src)) + +/mob/living/simple_animal/hostile/abnormality/giant/BreachEffect(mob/living/carbon/human/user, breach_type) + . = ..() + TryJump() + +//*****Work Mechanics***** +/mob/living/simple_animal/hostile/abnormality/giant/PostWorkEffect(mob/living/carbon/human/user, work_type, pe, work_time) + if(get_attribute_level(user, FORTITUDE_ATTRIBUTE) < 80) + datum_reference.qliphoth_change(-1) + if(istype(user.ego_gift_list[LEFTBACK], /datum/ego_gifts/giant)) + say("THAT'S MINE!!!") + return + +/mob/living/simple_animal/hostile/abnormality/giant/FailureEffect(mob/living/carbon/human/user, work_type, pe) + . = ..() + datum_reference.qliphoth_change(-1) + return + +//*****Breached attacks***** +/mob/living/simple_animal/hostile/abnormality/giant/proc/Ground_Smack() + can_act = FALSE + var/dir_to_target = get_cardinal_dir(get_turf(src), get_turf(target)) + var/turf/source_turf = get_turf(src) + var/turf/area_of_effect = list() + var/turf/middle_line = list() + var/upline = NORTH + var/downline = SOUTH + var/smash_length = 8 + var/smash_width = 2 + face_atom(target) + middle_line = getline(source_turf, get_ranged_target_turf(source_turf, dir_to_target, smash_length)) + if(dir_to_target == NORTH || dir_to_target == SOUTH) + upline = EAST + downline = WEST + for(var/turf/T in middle_line) + if(T.density) + break + for(var/turf/Y in getline(T, get_ranged_target_turf(T, upline, smash_width))) + if (Y.density) + break + if (Y in area_of_effect) + continue + area_of_effect += Y + for(var/turf/U in getline(T, get_ranged_target_turf(T, downline, smash_width))) + if (U.density) + break + if (U in area_of_effect) + continue + area_of_effect += U + if(!dir_to_target) + for(var/turf/TT in view(1, src)) + if (TT.density) + break + if (TT in area_of_effect) + continue + area_of_effect |= TT + if (!LAZYLEN(area_of_effect)) + return + for(var/turf/T in area_of_effect) + new/obj/effect/temp_visual/cult/sparks(T) + SLEEP_CHECK_DEATH(15) + playsound(get_turf(src), attack_sound, 75, 0, 3) + for(var/turf/T in area_of_effect) + new /obj/effect/temp_visual/smash_effect(T) + HurtInTurf(T, list(), melee_damage_upper, RED_DAMAGE, check_faction = TRUE, hurt_mechs = TRUE) + SLEEP_CHECK_DEATH(3) + can_act = TRUE + +/mob/living/simple_animal/hostile/abnormality/giant/proc/TryJump(atom/target) + if(!can_act) + return FALSE + if(jump_cooldown >= world.time) + return + var/inverse = FALSE + if(prob(50)) + inverse = TRUE + jump_cooldown = world.time + jump_cooldown_time //We reset the cooldown later if there are no targets + SLEEP_CHECK_DEATH(0.1 SECONDS) + var/list/potentialmarked = list() + var/list/marked = list() + var/mob/living/carbon/human/Y + for(var/mob/living/carbon/human/L in GLOB.player_list) + if(faction_check_mob(L, FALSE) || L.stat >= HARD_CRIT || L.sanity_lost || z != L.z) // Dead or in hard crit, insane, or on a different Z level. + continue + potentialmarked += L + var/numbermarked = 1 + round(LAZYLEN(potentialmarked) / 5, 1) //1 + 1 in 5 potential players, to the nearest whole number + for(var/i = numbermarked, i>=1, i--) + if(potentialmarked.len <= 0) + break + Y = pick(potentialmarked) + potentialmarked -= Y + if(Y.stat == DEAD || Y.is_working) + continue + marked+=Y + if(marked.len <= 0) //Oh no, everyone's dead! + jump_cooldown = world.time + return + can_act = FALSE + var/mob/living/carbon/human/final_target = pick(marked) + playsound(get_turf(final_target), 'sound/abnormalities/giant/jump_warning.ogg', 30, FALSE) + JumpAttack(final_target, inverse) + +/mob/living/simple_animal/hostile/abnormality/giant/proc/JumpAttack(atom/target, inverse = FALSE) + pixel_z = 128 + alpha = 0 + density = FALSE + var/turf/target_turf = get_turf(target) + var/spike_turf_dist = 8 + var/sweetspot = 0 + forceMove(target_turf) //look out, someone is rushing you! + if(inverse) + sweetspot = 8 + spike_turf_dist = 1 + new /obj/effect/temp_visual/giant_warning/pull(target_turf) + else + new /obj/effect/temp_visual/giant_warning(target_turf) + SLEEP_CHECK_DEATH(5 SECONDS) + animate(src, pixel_z = 0, alpha = 255, time = 5) + SLEEP_CHECK_DEATH(5) + density = TRUE + visible_message(span_danger("[src] drops down from the ceiling!")) + playsound(get_turf(src), 'sound/abnormalities/giant/land.ogg', 100, FALSE, 20) + var/obj/effect/temp_visual/decoy/D = new(get_turf(src), src) + animate(D, alpha = 0, transform = matrix()*2, time = 5) + for(var/turf/open/T in view(3, src)) + new /obj/effect/temp_visual/tile_broken(T) + for(var/turf/open/T in view(8, src)) + new /obj/effect/temp_visual/tile_broken/type_2(T) + if(get_dist(src, T) == spike_turf_dist) + new /obj/effect/temp_visual/thornspike(T) + continue + if(prob(20)) + new /obj/effect/temp_visual/tile_broken/type_3(T) + for(var/mob/living/L in livinginrange(15, src)) + shake_camera(L, 5, 5) + for(var/mob/living/L in view(8, src)) + var/dist = get_dist(src, L) + if(ishuman(L)) //Different damage formulae for humans vs mobs + L.deal_damage(clamp((15 * (2 ** (sweetspot - dist))), 15, 1000), RED_DAMAGE) //15-1000 damage scaling exponentially with distance. Since mistakes are much more likely, the cap is a bit more survivable + else + L.deal_damage(600 - ((dist > 2 ? dist : 0 )* 75), RED_DAMAGE) //0-600 damage scaling on distance, we don't want it oneshotting mobs + if(L == src || L.throwing) + continue + to_chat(L, span_userdanger("[src]'s ground slam shockwave sends you flying!")) + var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10)) + L.throw_at(thrownat, 8, 2, src, TRUE, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE) + if(L.health < 0) + L.gib() + can_act = TRUE + +/obj/effect/temp_visual/giant_warning + name = "approaching giant" + desc = "LOOK OUT!" + icon = 'icons/effects/96x96.dmi' + icon_state = "push_warning" + pixel_x = -32 + base_pixel_x = -32 + pixel_y = -32 + base_pixel_y = -32 + layer = POINT_LAYER//Sprite should always be visible + duration = 5 SECONDS + +/obj/effect/temp_visual/giant_warning/pull + icon_state = "pull_warning" diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/beanstalk.dm b/code/modules/mob/living/simple_animal/abnormality/teth/beanstalk.dm index 314cb432ed0d..7e023f70031d 100644 --- a/code/modules/mob/living/simple_animal/abnormality/teth/beanstalk.dm +++ b/code/modules/mob/living/simple_animal/abnormality/teth/beanstalk.dm @@ -36,6 +36,7 @@ observation_fail_message = "You begin to climb the beanstalk, but no matter how much you climb there's always more stalk. You peer at the clouds, squinting your eyes, but still can't see anyone..." var/climbing = FALSE + var/giant_countdown = 0 //Performing instinct work at >4 fortitude starts a special work /mob/living/simple_animal/hostile/abnormality/beanstalk/AttemptWork(mob/living/carbon/human/user, work_type) @@ -95,12 +96,138 @@ animate(user, alpha = 255,pixel_x = 0, pixel_z = -16, time = 3 SECONDS) user.pixel_z = 0 to_chat(user, span_userdanger("You return with the giant's treasure!")) + INVOKE_ASYNC(src, PROC_REF(Check_Treasure_Count), user) work_damage_amount = 7 climbing = FALSE +/mob/living/simple_animal/hostile/abnormality/beanstalk/proc/Check_Treasure_Count(mob/living/carbon/human/user) + giant_countdown += 1 + switch(giant_countdown) + if(1) + //change this to a sack of gold coins, or something to that effect + new /obj/item/coin/gold(get_turf(user)) + if(2) + var/obj/structure/musician/harp_magic/H = new(get_turf(user)) + H.say("Help master! A boy is stealing me!") + if(3) + new /mob/living/simple_animal/hostile/retaliate/goose/golden(get_turf(user)) + sleep(3 SECONDS) + var/mob/living/simple_animal/hostile/abnormality/giant/G = new(get_turf(src)) + visible_message(span_boldwarning("You hear leaves rustling far above the cell!")) + G.TryJump(user) + for(var/mob/M in GLOB.player_list) + var/check_z = M.z + if(isatom(M.loc)) + check_z = M.loc.z // So it plays even when you are in a locker/sleeper + if((check_z == z) && M.client) + to_chat(M, span_userdanger("Fee-fi-fo-fum, I smell the blood of an Englishman! Be he alive, be he dead, I'll grind his bones to make my bread!")) + /datum/ego_gifts/giant name = "Giant" icon_state = "giant" fortitude_bonus = 8 slot = LEFTBACK + +/mob/living/simple_animal/hostile/retaliate/goose/golden + name = "a goose that lays golden eggs" + desc = "We're rich!" + var/egg_type = /obj/item/food/egg/golden + health = 1500 + maxHealth = 1500 + faction = list("passive") + random_retaliate = FALSE + var/eggsleft = 3 + var/eggsFertile = FALSE + var/list/layMessage = EGG_LAYING_MESSAGES + var/attr_list = list() + var/list/feedMessages = list("She honks happily.") + food_type = list(/obj/item/food/grown/wheat, /obj/item/food/breadslice) + +/mob/living/simple_animal/hostile/retaliate/goose/golden/attackby(obj/item/O, mob/user, params)//re-used chicken code + if(is_type_in_list(O, food_type)) + if(!stat && eggsleft < 8) + var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]" + user.visible_message(feedmsg) + qdel(O) + eggsleft += 0.2 + else + to_chat(user, span_warning("[name] doesn't seem hungry!")) + else + ..() + +/mob/living/simple_animal/hostile/retaliate/goose/golden/Life() + . =..() + if(!.) + return + if((!stat && prob(3) && eggsleft > 0) && egg_type) + visible_message(span_alertalien("[src] [pick(layMessage)]")) + eggsleft-- + var/obj/item/E = new egg_type(get_turf(src)) + E.pixel_x = rand(-6,6) + E.pixel_y = rand(-6,6) + if(eggsFertile) + START_PROCESSING(SSobj, E) + +//*** Treasures ***// +/obj/item/food/egg/golden + name = "golden egg" + desc = "A golden egg!" + icon_state = "goldenegg" + food_reagents = list(/datum/reagent/consumable/eggyolk = 5, /datum/reagent/abnormality/ambrosia = 5) + tastes = list("your favorite food" = 4, "childhood memories" = 1) + microwaved_type = /obj/item/food/boiledegg + foodtypes = MEAT + w_class = WEIGHT_CLASS_TINY + var/stat_bonus = 5 + +/obj/item/food/egg/golden/attack_self(mob/living/user)//_attribute.dm for references to these procs + var/mob/living/carbon/human/H = user + if(!ishuman(user)) + return + var/atr_list = shuffle(H.attributes) + for(var/atr_type in atr_list)//generate a random list of attributes. You want this every time an egg is used to it picks random attributes. + var/datum/attribute/atr = H.attributes[atr_type] + if(!istype(atr)) + continue + if(atr.level >= 130)//too high? go for the next random attribute + continue + if(atr.level_limit < 130) + atr.level_limit += stat_bonus + if(atr.adjust_level(H, stat_bonus)) + to_chat(H, span_nicegreen("You eat the delicious [src], raising your [atr] attribute by [stat_bonus]!")) + qdel(src) + return + to_chat(H, span_warning("Your attributes are too high for the [src] to benefit you.")) + +/obj/item/food/egg/golden/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(!..()) //was it caught by a mob? + var/turf/T = get_turf(hit_atom) + new /obj/effect/decal/cleanable/food/egg_smudge(T) + reagents.expose(hit_atom, TOUCH) + qdel(src) + +/obj/structure/musician/harp_magic + name = "magical harp" + desc = "A magical harp that can continue playing while unattended. It may impose beneficial effects on its listeners." + icon = 'icons/obj/musician.dmi' + icon_state = "harp" + anchored = FALSE + density = TRUE + allowed_instrument_ids = list("sine") + can_play_unanchored = TRUE + var/is_healing + +/obj/structure/musician/harp_magic/interact(mob/user)//Janky, just like instrument code! + ..() + INVOKE_ASYNC(src, PROC_REF(healing_pulse),user) + +/obj/structure/musician/harp_magic/proc/healing_pulse(mob/living/user) + if(is_healing) + return + is_healing = TRUE + while(song.playing == TRUE) + for(var/mob/living/carbon/human/H in view(15)) + H.adjustSanityLoss(-1) + sleep(1 SECONDS) + is_healing = FALSE diff --git a/code/modules/paperwork/records/info/aleph.dm b/code/modules/paperwork/records/info/aleph.dm index 98f63c2bc57b..79e66f8a40a0 100644 --- a/code/modules/paperwork/records/info/aleph.dm +++ b/code/modules/paperwork/records/info/aleph.dm @@ -246,3 +246,16 @@ "As time goes on, this abnormality boosts your stats significantly.", "Working on the abnormality will cause it to set once more, and cause all of it's boosts to subside.", ) + +// The Giant Atop the Beanstalk +/* +/obj/item/paper/fluff/info/aleph/giant + abno_type = /mob/living/simple_animal/hostile/abnormality/giant + abno_code = "F-01-216" + no_archive = TRUE + abno_info = list( + "The Giant Atop the Beanstalk was discovered as a subordinate entity of another.", + "When the work result was Bad, the Qliphoth Counter lowered.", + "When an employee whose Fortitude was lower than Level 4 completed the work, the Qliphoth Counter decreased.", + "When Agent Yumi completed work while wearing the gift of F-03-16, Qliphoth Counter lowered.", + )*/ diff --git a/code/modules/projectiles/ammunition/ego_ammunition/special.dm b/code/modules/projectiles/ammunition/ego_ammunition/special.dm index bb212401cbc8..e0fd8c824071 100644 --- a/code/modules/projectiles/ammunition/ego_ammunition/special.dm +++ b/code/modules/projectiles/ammunition/ego_ammunition/special.dm @@ -51,3 +51,10 @@ projectile_type = /obj/projectile/bonebullet pellets = 4 variance = 16 + +/obj/item/ammo_casing/caseless/giant + name = "giant casing" + desc = "a casing" + projectile_type = /obj/projectile/giant_rocks + pellets = 8 + variance = 16 diff --git a/code/modules/projectiles/projectile/magic/abnormality.dm b/code/modules/projectiles/projectile/magic/abnormality.dm index a03864b9c399..3cd050c890b3 100644 --- a/code/modules/projectiles/projectile/magic/abnormality.dm +++ b/code/modules/projectiles/projectile/magic/abnormality.dm @@ -386,3 +386,28 @@ . = ..() hitsound = "sound/weapons/ego/rapier[pick(1,2)].ogg" animate(src, alpha = 255, time = 3) + +/obj/projectile/giant_rocks + name = "facility rubble" + desc = "Rubble and scrap thrown at a high velocity. Look out!" + icon_state = "wishing_rock" + hitsound = 'sound/weapons/genhit2.ogg' + damage_type = RED_DAMAGE + damage = 15 + spread = 60 + slur = 3 + eyeblur = 3 + +/obj/projectile/giant_rocks/Initialize() + . = ..() + var/rock_icon = pick("rock", "tile", "rod", "glass") + switch(rock_icon) + if("tile") + icon = 'icons/obj/tiles.dmi' + icon_state = "tile" + if("rod") + icon = 'icons/obj/stack_objects.dmi' + icon_state = "rods-1" + if("glass") + icon = 'icons/obj/shards.dmi' + icon_state = "small" diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi index 7023db2e2d50..2776cb67af1b 100644 Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index f3660297e74a..431857446cc3 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index c1be25e7456b..9b211fce112d 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/musician.dmi b/icons/obj/musician.dmi index c3e0f21f05aa..3ce47722aab0 100644 Binary files a/icons/obj/musician.dmi and b/icons/obj/musician.dmi differ diff --git a/lobotomy-corp13.dme b/lobotomy-corp13.dme index 348e8208b34f..410e6b1c3c3b 100644 --- a/lobotomy-corp13.dme +++ b/lobotomy-corp13.dme @@ -2829,6 +2829,7 @@ #include "code\modules\mob\living\simple_animal\abnormality\aleph\blue_star.dm" #include "code\modules\mob\living\simple_animal\abnormality\aleph\censored.dm" #include "code\modules\mob\living\simple_animal\abnormality\aleph\distortedform.dm" +#include "code\modules\mob\living\simple_animal\abnormality\aleph\giant.dm" #include "code\modules\mob\living\simple_animal\abnormality\aleph\last_shot.dm" #include "code\modules\mob\living\simple_animal\abnormality\aleph\melting_love.dm" #include "code\modules\mob\living\simple_animal\abnormality\aleph\mountain.dm" diff --git a/sound/abnormalities/giant/attack.ogg b/sound/abnormalities/giant/attack.ogg new file mode 100644 index 000000000000..491aa352ffe8 Binary files /dev/null and b/sound/abnormalities/giant/attack.ogg differ diff --git a/sound/abnormalities/giant/jump_warning.ogg b/sound/abnormalities/giant/jump_warning.ogg new file mode 100644 index 000000000000..f69b1eb03f36 Binary files /dev/null and b/sound/abnormalities/giant/jump_warning.ogg differ diff --git a/sound/abnormalities/giant/land.ogg b/sound/abnormalities/giant/land.ogg new file mode 100644 index 000000000000..211fda205820 Binary files /dev/null and b/sound/abnormalities/giant/land.ogg differ