From 6f3e41ecf01159adf684df3239dce4efe09afca8 Mon Sep 17 00:00:00 2001 From: Alberyk Date: Wed, 3 May 2017 16:23:43 -0300 Subject: [PATCH] Adds the rat king (#2130) Ports the rat king from apollo, as an admin tool for now. The rat king can collect mouse as he walks by, getting stronger, and unlocking some skills, it also can speak to all mouse in the world via a special skill. --- baystation12.dme | 1 + code/global.dm | 1 + .../living/simple_animal/friendly/mouse.dm | 32 +- .../living/simple_animal/friendly/ratking.dm | 278 ++++++++++++++++++ code/modules/ventcrawl/ventcrawl.dm | 3 +- 5 files changed, 305 insertions(+), 10 deletions(-) create mode 100644 code/modules/mob/living/simple_animal/friendly/ratking.dm diff --git a/baystation12.dme b/baystation12.dme index 2e5479efa66..4665b2cf95d 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1592,6 +1592,7 @@ #include "code\modules\mob\living\simple_animal\friendly\lizard.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" #include "code\modules\mob\living\simple_animal\friendly\mushroom.dm" +#include "code\modules\mob\living\simple_animal\friendly\ratking.dm" #include "code\modules\mob\living\simple_animal\friendly\slime.dm" #include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm" #include "code\modules\mob\living\simple_animal\friendly\tomato.dm" diff --git a/code/global.dm b/code/global.dm index 561da51effa..e4393e0466a 100644 --- a/code/global.dm +++ b/code/global.dm @@ -14,6 +14,7 @@ var/global/list/med_hud_users = list() // List of all entities using var/global/list/sec_hud_users = list() // List of all entities using a security HUD. var/global/list/hud_icon_reference = list() var/global/list/janitorial_supplies = list() // List of all the janitorial supplies on the map that the PDA cart may be tracking. +var/global/list/world_mouses = list() //List of all mice in the world var/global/list/listening_objects = list() // List of objects that need to be able to hear, used to avoid recursive searching through contents. diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 95379c90a3a..99b2cb56b13 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -56,7 +56,6 @@ kitchen_tag = "rodent" - /mob/living/simple_animal/mouse/Life() if(..()) @@ -80,7 +79,12 @@ else if ((world.time - timeofdeath) > decompose_time) dust() - + +/mob/living/simple_animal/mouse/Destroy() + world_mouses -= src + + return ..() + //Pixel offsetting as they scamper around /mob/living/simple_animal/mouse/Move() if(..()) @@ -120,6 +124,8 @@ //verbs += /mob/living/simple_animal/mouse/proc/squeak_soft //verbs += /mob/living/simple_animal/mouse/proc/squeak_loud(1) + world_mouses += src + /mob/living/simple_animal/mouse/speak_audio() squeak_soft(0) @@ -142,8 +148,6 @@ if(client) client.time_died_as_mouse = world.time - - //Plays a sound. //This is triggered when a mob steps on an NPC mouse, or manually by a playermouse /mob/living/simple_animal/mouse/proc/squeak(var/manual = 1) @@ -153,7 +157,6 @@ log_say("[key_name(src)] squeaks! ",ckey=key_name(src)) - //Plays a random selection of four sounds, at a low volume //This is triggered randomly periodically by any mouse, or manually /mob/living/simple_animal/mouse/proc/squeak_soft(var/manual = 1) @@ -228,6 +231,18 @@ squeak(0) else squeak_loud(0)//You trod on its tail + + if(!health) + return + + if(istype(AM,/mob/living/simple_animal/mouse/king)) + var/mob/living/simple_animal/mouse/king/K = AM + if(!K.health) + return + + src.visible_message("[src] joins the [K.swarm_name] of \the [K]", \ + "We join our brethren in \the [K.swarm_name]. Long live \the [K].") + K.absorb(src) ..() /mob/living/simple_animal/mouse/death() @@ -237,16 +252,15 @@ if(client) client.time_died_as_mouse = world.time + + world_mouses -= src + ..() /mob/living/simple_animal/mouse/dust() ..(anim = "dust_[body_color]", remains = /obj/effect/decal/remains/mouse, iconfile = 'icons/mob/mouse.dmi') - - - - /* * Mouse types */ diff --git a/code/modules/mob/living/simple_animal/friendly/ratking.dm b/code/modules/mob/living/simple_animal/friendly/ratking.dm new file mode 100644 index 00000000000..e2a998bb9bf --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/ratking.dm @@ -0,0 +1,278 @@ +#define RAT_MAYOR_LEVEL 1 +#define RAT_BARON_LEVEL 3 +#define RAT_DUKE_LEVEL 5 +#define RAT_KING_LEVEL 10 +#define RAT_EMPEROR_LEVEL 20 +#define RAT_SAVIOR_LEVEL 30 +#define RAT_GOD_LEVEL 50 + + +/proc/announceToRodents(var/message) + for(var/R in world_mouses) + R << message + +/mob/living/simple_animal/mouse/king + attacktext = "bitten" + a_intent = "harm" + + icon_state = "mouse_gray" + item_state = "mouse_gray" + icon_living = "mouse_gray" + icon_dead = "mouse_gray_dead" + icon_rest = "mouse_gray_sleep" + + var/swarm_name = "peasentry" + var/announce_name = "Request" + var/list/rats = list() + +/mob/living/simple_animal/mouse/king/New() + ..() + + update() + + icon_state = initial(icon_state) + icon_living = initial(icon_living) + icon_dead = initial(icon_dead) + body_color = "gray" + + say_dead_direct("An heir to the rat throne has risen, all rejoice and celebrate.") + announceToRodents("The rat king has risen! Go at once and join his kingdom, long live the king!") + +/mob/living/simple_animal/mouse/king/death() + while(rats.len) + eject(rats[1], 1) + + ..() + +/mob/living/simple_animal/mouse/king/Move() + ..() + + for(var/image/I in overlays) + I.dir = src.dir + +/mob/living/simple_animal/mouse/king/proc/update_icon() + ..() + + src.overlays.Cut() + + for(var/mob/living/simple_animal/mouse/R in rats) + var/image/rat_overlay = image('icons/mob/animal.dmi', "[R.icon_state]") + rat_overlay.dir = src.dir + var/matrix/M = matrix() + M.Translate(rand(-6, 6), rand(-4, 8)) + rat_overlay.transform = M + src.overlays += rat_overlay + +/mob/living/simple_animal/mouse/king/proc/update() + if( rats.len >= RAT_GOD_LEVEL) + name = "rat god" + swarm_name = "creation" + announce_name = "Commandment" + desc = "A titanic swarm of rats." + attacktext = "swarmed" + melee_damage_lower = 15 + melee_damage_upper = 20 + maxHealth = 50 + health = 50 + mob_size = 10 + universal_speak = 1 + else if(rats.len >= RAT_SAVIOR_LEVEL) + name = "rat savior" + swarm_name = "flock" + announce_name = "Pronouncement" + desc = "A massive swarm of rats." + attacktext = "swarmed" + melee_damage_lower = 10 + melee_damage_upper = 10 + maxHealth = 40 + health = 40 + mob_size = 9 + else if(rats.len >= RAT_EMPEROR_LEVEL) + name = "rat emperor" + swarm_name = "empire" + announce_name = "Command" + desc = "A large swarm of rats." + attacktext = "swarmed" + melee_damage_lower = 7 + melee_damage_upper = 5 + maxHealth = 35 + health = 35 + mob_size = 8 + else if(rats.len >= RAT_KING_LEVEL) + name = "rat king" + swarm_name = "kingdom" + announce_name = "Decree" + desc = "A big swarm of rats." + attacktext = "swarmed" + melee_damage_lower = 5 + melee_damage_upper = 5 + maxHealth = 30 + health = 30 + mob_size = 7 + else if(rats.len >= RAT_DUKE_LEVEL) + name = "rat duke" + swarm_name = "duchy" + announce_name = "Decree" + desc = "A swarm of rats." + attacktext = "bitten" + maxHealth = 25 + health = 25 + mob_size = 6 + else if(rats.len >= RAT_BARON_LEVEL) + name = "rat baron" + swarm_name = "barony" + announce_name = "Decree" + desc = "A group of rats." + attacktext = "bitten" + maxHealth = 20 + health = 20 + mob_size = 4 + else if(rats.len >= RAT_MAYOR_LEVEL) + name = "rat mayor" + swarm_name = "hamlet" + announce_name = "Decree" + desc = "A couple of rats." + attacktext = "bitten" + maxHealth = 15 + health = 15 + mob_size = 3 + else + name = "rat peasant" + swarm_name = "peasentry" + announce_name = "Request" + desc = "A single rat. This one seems special." + attacktext = "scratched" + maxHealth = 10 + health = 10 + mob_size = 2 + + desc += " There are [rats.len] rats in his [swarm_name]." + real_name = name + + update_icon() + +/mob/living/simple_animal/mouse/king/splat() + src.apply_damage(5, BRUTE) + +/mob/living/simple_animal/mouse/king/verb/kingDecree() + set category = "Abilities" + set name = "Decree" + + if( !health ) + usr << "You are dead, you cannot use any abilities!" + return + + var/input = sanitize(input(usr, "Please enter the [lowertext( announce_name )] for your whole kingdom.", "What?", "") as message|null, extra = 0) + + if( !input ) + return + + var/full_message = {"

[src]\'s [announce_name]

+[input]
"} + + announceToRodents( "[full_message]" ) + +/mob/living/simple_animal/mouse/king/verb/roar() + set category = "Abilities" + set name = "Mighty Roar" + + if(!health) + usr << "You are dead, you cannot use any abilities!" + return + + if(last_special > world.time) + usr << "We must wait a little while before we can use this ability again!" + return + + if(!canRoar()) + usr << "Our [swarm_name] must grow larger before we can use this ability!" + return + + src.visible_message("[src] lets loose a mighty roar!") + for( var/obj/machinery/light/L in range( 3, src )) + if( canRoarBreakLights() && prob(( rats.len/RAT_EMPEROR_LEVEL )*100 )) + L.broken() + else + L.flicker() + last_special = world.time + 30 + +/mob/living/simple_animal/mouse/king/verb/devourdead(mob/target as mob in oview()) + set category = "Abilities" + set name = "Devour Body" + + if(!Adjacent(target)) + return + + if(!health) + usr << "You are dead, you cannot use any abilities!" + return + + if(!canEatCorpse()) + usr << "Our [swarm_name] must grow larger before we can use this ability!" + return + + if(last_special > world.time) + usr << "We must wait a little while before we can use this ability again!" + return + + if(target.stat != DEAD) + usr << "We can only devour the dead!" + return + + usr.visible_message("\The [usr] swarms the body of \the [target], ripping flesh from bone!" ) + + if(!do_after(usr,200)) + usr<< "You need to wait longer to consume the body of [target]!" + return 0 + + src.visible_message("\The [usr] consumed the body of \the [target]!") + target.gib() + rejuvenate() + updatehealth() + last_special = world.time + 100 + return + +/mob/living/simple_animal/mouse/king/proc/absorb(var/mob/living/simple_animal/mouse/R, var/update = 1) + if(!(R in rats)) + R.forceMove(src) + rats += R + + if( update ) + update() + +/mob/living/simple_animal/mouse/king/proc/eject(var/mob/living/simple_animal/mouse/R, var/update = 1) + if(R in rats) + R.forceMove(get_turf(src)) + rats -= R + + if(update) + update() + +/mob/living/simple_animal/mouse/king/proc/kingdomMessage(var/message, var/king_message) + for(var/R in rats) + R << message + + if(king_message) + src << king_message + else + src << message + +/mob/living/simple_animal/mouse/king/proc/canNibbleWire() + if(rats.len >= RAT_MAYOR_LEVEL) + return 1 + return 0 + +/mob/living/simple_animal/mouse/king/proc/canRoar() + if(rats.len >= RAT_BARON_LEVEL) + return 1 + return 0 + +/mob/living/simple_animal/mouse/king/proc/canRoarBreakLights() + if(rats.len >= RAT_EMPEROR_LEVEL) + return 1 + return 0 + +/mob/living/simple_animal/mouse/king/proc/canEatCorpse() + if(rats.len >= RAT_KING_LEVEL) + return 1 + return 0 diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 6bc2058eb55..f377bae3d93 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -10,7 +10,8 @@ var/global/list/can_enter_vent_with = list( /obj/item/device/radio/borg, /obj/item/weapon/holder, /obj/machinery/camera, - /mob/living/simple_animal/borer + /mob/living/simple_animal/borer, + /mob/living/simple_animal/mouse ) /mob/living/var/list/icon/pipes_shown = list()