From 2f92ba494e80808e9e07c9787eb191e2637eea3e Mon Sep 17 00:00:00 2001 From: "vageyenaman@gmail.com" Date: Mon, 9 Jan 2012 01:48:38 +0000 Subject: [PATCH] Possibly the finishing touches to the telecomms prototype. They will be included in the game soon-ish. Some work on critters. Added a new critter type: the VISCERATORS. (http://dl.dropbox.com/u/10657252/SS13/Manhacks.PNG) Includes a small new audio file. They'll probably be created with a traitor item or a box-o-hacks in the armory. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2932 316c924e-a436-60f5-8080-3fe189b3f50e --- code/game/machinery/telecomms/broadcaster.dm | 49 +++++++--- code/game/machinery/telecomms/logbrowser.dm | 4 +- .../telecomms/machine_interactions.dm | 8 +- .../machinery/telecomms/telecomunications.dm | 92 +++++++++++++++--- code/game/mecha/mecha.dm | 22 ++++- code/game/objects/radio/radio.dm | 12 ++- code/modules/critters/critter.dm | 14 +++ code/modules/critters/critter_AI.dm | 73 ++++++++++---- code/modules/critters/critter_defenses.dm | 11 ++- code/modules/critters/critters.dm | 33 +++++++ code/modules/mob/mob_helpers.dm | 18 ++++ icons/mob/critter.dmi | Bin 49836 -> 49841 bytes sound/weapons/bladeslice.wav | Bin 0 -> 35324 bytes 13 files changed, 282 insertions(+), 54 deletions(-) create mode 100644 sound/weapons/bladeslice.wav diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 437ee6daeb3..203635dc02f 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -21,14 +21,6 @@ if(signal.data["message"]) - - /* ###### Broadcast a message using signal.data ###### */ - Broadcast_Message(signal.data["connection"], signal.data["mob"], - signal.data["vmask"], signal.data["vmessage"], - signal.data["radio"], signal.data["message"], - signal.data["name"], signal.data["job"], - signal.data["realname"], signal.data["vname"]) - signal.data["done"] = 1 // mark the signal as being broadcasted // Search for the original signal and mark it as done as well @@ -36,6 +28,16 @@ if(original) original.data["done"] = 1 + if(signal.data["slow"] > 0) + sleep(signal.data["slow"]) // simulate the network lag if necessary + + /* ###### Broadcast a message using signal.data ###### */ + Broadcast_Message(signal.data["connection"], signal.data["mob"], + signal.data["vmask"], signal.data["vmessage"], + signal.data["radio"], signal.data["message"], + signal.data["name"], signal.data["job"], + signal.data["realname"], signal.data["vname"],, signal.data["compression"]) + /* --- Do a snazzy animation! --- */ flick("broadcaster_send", src) @@ -82,12 +84,16 @@ 1 -- Will only broadcast to intercoms 2 -- Will only broadcast to intercoms and station-bounced radios + @param compression: + If 0, the signal is audible + If nonzero, the signal may be partially inaudible or just complete gibberish. + **/ /proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M, var/vmask, var/vmessage, var/obj/item/device/radio/radio, var/message, var/name, var/job, var/realname, var/vname, - var/filtertype) + var/filtertype, var/compression) /* ###### Prepare the radio connection ###### */ @@ -133,6 +139,7 @@ // Did not understand the message: var/list/heard_voice = list() // voice message (ie "chimpers") var/list/heard_garbled = list() // garbled message (ie "f*c* **u, **i*er!") + var/list/heard_gibberish= list() // completely screwed over message (ie "F%! (O*# *#!<>&**%!") for (var/mob/R in receive) @@ -141,6 +148,12 @@ if (R.client && R.client.STFU_radio) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. continue + + // --- Check for compression --- + if(compression > 0) + heard_gibberish += R + continue + // --- Can understand the speech --- if (R.say_understands(M)) @@ -166,7 +179,7 @@ /* ###### Begin formatting and sending the message ###### */ - if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled)) + if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_gibberish)) /* --- Some miscellaneous variables to format the string output --- */ var/part_a = "" // goes in the actual output @@ -294,11 +307,25 @@ quotedmsg = M.say_quote(stars(message)) var/rendered = "[part_a][vname][part_b][quotedmsg][part_c]" - for (var/mob/R in heard_voice) + for (var/mob/R in heard_garbled) if(istype(R, /mob/living/silicon/ai)) R.show_message("[part_a][vname][part_b][quotedmsg][part_c]", 2) else R.show_message(rendered, 2) + /* --- Complete gibberish. Usually happens when there's a compressed message --- */ + + if (length(heard_gibberish)) + quotedmsg = M.say_quote(Gibberish(message, compression + 50)) + world << "Gibberish: [quotedmsg]" + var/rendered = "[part_a][Gibberish(M.real_name, compression + 50)][part_b][quotedmsg][part_c]" + + for (var/mob/R in heard_gibberish) + if(istype(R, /mob/living/silicon/ai)) + R.show_message("[part_a][Gibberish(realname, compression + 50)] ([Gibberish(job, compression + 50)]) [part_b][quotedmsg][part_c]", 2) + else + R.show_message(rendered, 2) + + diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index f28f31d4ed5..90d895842e5 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -93,8 +93,8 @@ if(language == "Human" || universal_translate || C.parameters["uspeech"]) dat += "Data type: [C.input_type]
" - dat += "Orator: [C.parameters["name"]] (Job: [C.parameters["job"]])
" - dat += "Race: [race]
" + dat += "Source: [C.parameters["name"]] (Job: [C.parameters["job"]])
" + dat += "Class: [race]
" dat += "Contents: \"[C.parameters["message"]]\"
" diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index ff59f3f9585..2abb7af0406 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -130,20 +130,26 @@ if(href_list["link"]) if(P.buffer) - if( (!(src in P.buffer.links)) && (!(P.buffer in src.links))) + if(!(src in P.buffer.links)) P.buffer.links.Add(src) + + if(!(P.buffer in src.links)) src.links.Add(P.buffer) + temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-" + else temp = "-% Unable to acquire buffer %-" if(href_list["buffer"]) + temp = "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-" P.buffer = src if(href_list["flush"]) + temp = "-% Buffer successfully flushed. %-" P.buffer = null diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index b1e7e627435..eece6b6c1b9 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -24,21 +24,62 @@ machinetype = 0 // just a hacky way of preventing alike machines from pairing - proc/relay_information(datum/signal/signal, filter, amount) + proc/relay_information(datum/signal/signal, filter, copysig, amount) // relay signal to all linked machinery that are of type [filter]. If signal has been sent [amount] times, stop sending var/send_count = 0 + + // Loop through all linked machines and send the signal or copy. + for(var/obj/machinery/telecomms/machine in links) if(filter && !istype( machine, text2path(filter) )) continue if(amount && send_count >= amount) break + // If we're sending a copy, be sure to create the copy for EACH machine and paste the data + var/datum/signal/copy = new + if(copysig) + + copy.transmission_method = 2 + copy.frequency = signal.frequency + // Copy the main data contents! Workaround for some nasty bug where the actual array memory is copied and not its contents. + copy.data = list( + + "mob" = signal.data["mob"], + "mobtype" = signal.data["mobtype"], + "realname" = signal.data["realname"], + "name" = signal.data["name"], + "job" = signal.data["job"], + "key" = signal.data["key"], + "vmessage" = signal.data["vmessage"], + "vname" = signal.data["vname"], + "vmask" = signal.data["vmask"], + "compression" = signal.data["compression"], + "message" = signal.data["message"], + "connection" = signal.data["connection"], + "radio" = signal.data["radio"], + "slow" = signal.data["slow"] + ) + + // Keep the "original" signal constant + if(!copy.data["original"]) + copy.data["original"] = signal + else + copy.data["original"] = signal.data["original"] + + else + del(copy) + + send_count++ spawn() - machine.receive_information(signal, src) + if(copysig && copy) + machine.receive_information(copy, src) + else + machine.receive_information(signal, src) return send_count @@ -74,6 +115,8 @@ The receiver idles and receives messages from subspace-compatible radio equipment; primarily headsets. They then just relay this information to all linked devices, which can would probably be network buses. + + Link to Processor Units in case receiver can't send to bus units. */ /obj/machinery/telecomms/receiver @@ -93,12 +136,13 @@ if(is_freq_listening(signal)) // detect subspace signals - var/datum/signal/copy = new - copy.copy_from(signal) // copy information to new signal - copy.data["original"] = signal - relay_information(copy) // ideally relay the information to bus units + var/sendbus = relay_information(signal, "/obj/machinery/telecomms/bus", 1) // ideally relay the copied information to bus units + /* We can't send the signal to a bus, so we send it to a processor */ + if(!sendbus) + signal.data["slow"] += rand(5, 10) // slow the signal down + relay_information(signal, "/obj/machinery/telecomms/processor", 1) // send copy to processors /* @@ -107,6 +151,8 @@ They transfer uncompressed subspace packets to processor units, and then take the processed packet to a server for logging. + + Link to a subspace broadcaster if it can't send to a server. */ /obj/machinery/telecomms/bus @@ -126,15 +172,21 @@ if(signal.data["compression"]) // if signal is still compressed from subspace transmission // send to one linked processor unit - var/send_to_processor = relay_information(signal, "/obj/machinery/telecomms/processor", 1) + var/send_to_processor = relay_information(signal, "/obj/machinery/telecomms/processor") if(!send_to_processor) // failed to send to a processor, relay information anyway - relay_information(signal, "/obj/machinery/telecomms/server") + signal.data["slow"] += rand(1, 5) // slow the signal down only slightly + relay_information(signal, "/obj/machinery/telecomms/server", 1) else // the signal has been decompressed by a processor unit // send to all linked server units - relay_information(signal, "/obj/machinery/telecomms/server") + var/sendserver = relay_information(signal, "/obj/machinery/telecomms/server", 1) + + // Can't send to a single server, send to a broadcaster instead! But it needs a processor to do this + if(!sendserver) + signal.data["slow"] += rand(0, 1) // slow the signal down only slightly + relay_information(signal, "/obj/machinery/telecomms/broadcaster") @@ -142,6 +194,8 @@ The processor is a very simple machine that decompresses subspace signals and transfers them back to the original bus. It is essential in producing audible data. + + Link to servers if bus is not present */ /obj/machinery/telecomms/processor @@ -159,7 +213,12 @@ if(is_freq_listening(signal)) signal.data["compression"] = 0 // uncompress subspace signal - relay_direct_information(signal, machine_from) // send the signal back to the machine + + if(istype(machine_from, /obj/machinery/telecomms/bus)) + relay_direct_information(signal, machine_from) // send the signal back to the machine + + else // no bus detected - send the signal to servers instead + relay_information(signal, "/obj/machinery/telecomms/server", 1) @@ -186,11 +245,11 @@ receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) - if(signal.data["message"] && !signal.data["compression"]) + if(signal.data["message"]) if(is_freq_listening(signal)) - // if signal contains discernable data + // If signal has a message and appropriate frequency update_logs() @@ -208,6 +267,15 @@ log.parameters["realname"] = signal.data["realname"] log.parameters["uspeech"] = M.universal_speak + // If the signal is still compressed, make the log entry gibberish + if(signal.data["compression"] > 0) + log.parameters["message"] = Gibberish(signal.data["message"], signal.data["compression"] + 50) + log.parameters["job"] = Gibberish(signal.data["job"], signal.data["compression"] + 50) + log.parameters["name"] = Gibberish(signal.data["name"], signal.data["compression"] + 50) + log.parameters["realname"] = Gibberish(signal.data["realname"], signal.data["compression"] + 50) + log.parameters["vname"] = Gibberish(signal.data["vname"], signal.data["compression"] + 50) + log.input_type = "Corrupt File" + log_entries.Add(log) var/identifier = num2text( rand(-1000,1000) + world.time ) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index e00cebaade5..d404c4345c2 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -427,7 +427,27 @@ src.occupant_message("\blue The [user]'s claws are stopped by the armor.") for (var/mob/V in viewers(src)) if(V.client && !(V.blinded)) - V.show_message("\blue The [user] rebounds off the [src.name] armor!", 1) + V.show_message("\blue The [user] rebounds off [src.name]'s armor!", 1) + return + + +/obj/mecha/proc/attack_critter(obj/effect/critter/C) + src.log_message("Attack by creature. Attacker - [C].",1) + var/damage = max(0, rand(C.melee_damage_lower - 5, C.melee_damage_upper - 5 )) + + if(!prob(src.deflect_chance) && damage > 0) + src.take_damage(damage) + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + playsound(src.loc, "sparks", 50, 1) + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("\red [C] hits [src.name]'s armor!", 1) + else + src.log_append_to_last("Armor saved.") + src.occupant_message("\blue [C]'s attack is stopped by the armor.") + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("\blue [C] rebounds off [src.name]'s armor!", 1) return diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm index 7a11e2f59c5..a23b3e710f6 100644 --- a/code/game/objects/radio/radio.dm +++ b/code/game/objects/radio/radio.dm @@ -286,10 +286,11 @@ var/GLOBAL_RADIO_TYPE = 0 // radio type to use // so that they can be logged even AFTER the mob is deleted or something // Other tags: - "compression" = 1, // compressed radio signal + "compression" = rand(45,50), // compressed radio signal "message" = message, // the actual sent message "connection" = connection, // the radio connection to use - "radio" = src // stores the radio used for transmission + "radio" = src, // stores the radio used for transmission + "slow" = 0 // how much to sleep() before broadcasting - simulates net lag ) signal.frequency = connection.frequency // Quick frequency set @@ -328,10 +329,11 @@ var/GLOBAL_RADIO_TYPE = 0 // radio type to use "vname" = M.voice_name, // the name to display if the voice wasn't understood "vmask" = voicemask, // 1 if the mob is using a voice gas mas - "compression" = 1, // compressed radio signal + "compression" = 0, // uncompressed radio signal "message" = message, // the actual sent message "connection" = connection, // the radio connection to use - "radio" = src // stores the radio used for transmission + "radio" = src, // stores the radio used for transmission + "slow" = 0 ) signal.frequency = connection.frequency // Quick frequency set @@ -350,7 +352,7 @@ var/GLOBAL_RADIO_TYPE = 0 // radio type to use Broadcast_Message(connection, M, voicemask, M.voice_message, src, message, displayname, jobname, real_name, M.voice_name, - filter_type) + filter_type, signal.data["compression"]) diff --git a/code/modules/critters/critter.dm b/code/modules/critters/critter.dm index 96daac131c9..9c49993f19e 100644 --- a/code/modules/critters/critter.dm +++ b/code/modules/critters/critter.dm @@ -21,6 +21,8 @@ wanderer = 1 //Will open doors it bumps ignoring access opensdoors = 0 + //Will randomly travel through vents + ventcrawl = 0 //Internal tracking ignore frustration = 0 @@ -32,6 +34,10 @@ target = null oldtarget_name = null target_lastloc = null + + thinkspeed = 15 + chasespeed = 4 + wanderspeed = 10 //The last guy who attacked it attacker = null //Will not attack this thing @@ -47,6 +53,11 @@ atksame = 0 atkmech = 0 + //Attacks syndies/traitors (distinguishes via mind) + atksynd = 1 + //Attacks things NOT in its obj/req_access list + atkreq = 0 + //Damage multipliers brutevuln = 1 firevuln = 1 @@ -59,7 +70,10 @@ //Basic attack message when they move to attack and attack angertext = "charges at" attacktext = "attacks" + deathtext = "dies!" + chasestate = null // the icon state to use when attacking or chasing a target + attackflick = null // the icon state to flick when it attacks attack_sound = null // the sound it makes when it attacks! attack_speed = 25 // delay of attack diff --git a/code/modules/critters/critter_AI.dm b/code/modules/critters/critter_AI.dm index 18e0fac6e46..855b7133bb3 100644 --- a/code/modules/critters/critter_AI.dm +++ b/code/modules/critters/critter_AI.dm @@ -13,7 +13,7 @@ if("thinking") src.attack = 0 src.target = null - sleep(15) + sleep(thinkspeed) walk_to(src,0) if (src.aggressive) seek_target() if (src.wanderer && !src.target) src.task = "wandering" @@ -29,11 +29,13 @@ var/mob/living/carbon/M = src.target ChaseAttack() src.task = "attacking" + if(chasestate) + icon_state = chasestate src.anchored = 1 src.target_lastloc = M.loc else var/turf/olddist = get_dist(src, src.target) - walk_to(src, src.target,1,4) + walk_to(src, src.target,1,chasespeed) if ((get_dist(src, src.target)) >= (olddist)) src.frustration++ else @@ -45,6 +47,8 @@ if ((get_dist(src, src.target) > 1) || ((src.target:loc != src.target_lastloc))) src.anchored = 0 src.task = "chasing" + if(chasestate) + icon_state = chasestate else if (get_dist(src, src.target) <= 1) var/mob/living/carbon/M = src.target @@ -58,20 +62,25 @@ src.attacking = 0 else if(M!=null) - if(M.health < 0) - src.task = "thinking" - src.target = null - src.anchored = 0 - src.last_found = world.time - src.frustration = 0 - src.attacking = 0 + if(ismob(src.target)) + if(M.health < 0) + src.task = "thinking" + src.target = null + src.anchored = 0 + src.last_found = world.time + src.frustration = 0 + src.attacking = 0 else src.anchored = 0 src.attacking = 0 src.task = "chasing" + if(chasestate) + icon_state = chasestate if("wandering") + if(chasestate) + icon_state = initial(icon_state) patrol_step() - sleep(10) + sleep(wanderspeed) spawn(8) process() return @@ -112,29 +121,57 @@ if (src.target) src.task = "chasing" break + + // Ignore syndicates and traitors if specified + if(!atksynd && C.mind) + var/datum/mind/synd_mind = C.mind + if( synd_mind.special_role == "Syndicate" || synd_mind.special_role == "traitor" ) + continue if((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if(istype(C, /mob/living/carbon/) && !src.atkcarbon) continue if(istype(C, /mob/living/silicon/) && !src.atksilicon) continue + if(atkreq) + if(src.allowed(C)) continue if(C.health < 0) continue if(istype(C, /mob/living/carbon/) && src.atkcarbon) src.attack = 1 if(istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1 + if(atkreq) + if(!src.allowed(C)) src.attack = 1 if(src.attack) T = C break if(!src.attack) for(var/obj/effect/critter/C in view(src.seekrange,src)) - if(istype(C, /obj/effect/critter) && !src.atkcritter) continue - if(istype(C, /obj/mecha) && !src.atkmech) continue + if(!src.atkcritter) continue if(C.health <= 0) continue - if(istype(C, /obj/effect/critter) && src.atkcritter) + if(src.atkcritter) if((istype(C, src.type) && !src.atksame) || (C == src)) continue src.attack = 1 - if(istype(C, /obj/mecha) && src.atkmech) src.attack = 1 if(src.attack) T = C break + if(!src.attack) + for(var/obj/mecha/C in view(src.seekrange,src)) + if(!C.occupant) continue + + if(atkreq && C.occupant) + if(src.allowed(C.occupant)) continue + + if(!atksynd && C.occupant) + if(C.occupant.mind) + var/datum/mind/synd_mind = C.occupant.mind + if( synd_mind.special_role == "Syndicate" || synd_mind.special_role == "traitor" ) + continue + + if(!src.atkmech) continue + if(C.health <= 0) continue + if(src.atkmech) src.attack = 1 + if(src.attack) + T = C + break + if(src.attack) src.target = T src.oldtarget_name = T:name @@ -150,10 +187,11 @@ RunAttack() src.attacking = 1 - for(var/mob/O in viewers(src, null)) - O.show_message("\red [src] [src.attacktext] [src.target]!", 1) if(ismob(src.target)) + for(var/mob/O in viewers(src, null)) + O.show_message("\red [src] [src.attacktext] [src.target]!", 1) + var/damage = rand(melee_damage_lower, melee_damage_upper) if(istype(target, /mob/living/carbon/human)) @@ -172,7 +210,8 @@ if(isobj(src.target)) if(istype(target, /obj/mecha)) - src.target:take_damage(rand(melee_damage_lower,melee_damage_upper)) + //src.target:take_damage(rand(melee_damage_lower,melee_damage_upper)) + src.target:attack_critter(src) else src.target:TakeDamage(rand(melee_damage_lower,melee_damage_upper)) spawn(attack_speed) diff --git a/code/modules/critters/critter_defenses.dm b/code/modules/critters/critter_defenses.dm index b69b4fbc5af..7e0b83a578e 100644 --- a/code/modules/critters/critter_defenses.dm +++ b/code/modules/critters/critter_defenses.dm @@ -13,7 +13,7 @@ Contains the procs that control attacking critters if("fire") damage = W.force * firevuln if("brute") damage = W.force * brutevuln TakeDamage(damage) - if(src.defensive) Target_Attacker(user) + if(src.defensive && alive) Target_Attacker(user) return @@ -46,9 +46,10 @@ Contains the procs that control attacking critters if(!target) return src.target = target src.oldtarget_name = target:name - if(task != "chasing" || task != "attacking") - for(var/mob/O in viewers(src, null)) - O.show_message("\red [src] [src.angertext] at [target:name]!", 1) + if(task != "chasing" && task != "attacking") + if(angertext && angertext != "") + for(var/mob/O in viewers(src, null)) + O.show_message("\red [src] [src.angertext] at [target:name]!", 1) src.task = "chasing" return @@ -70,7 +71,7 @@ Contains the procs that control attacking critters src.anchored = 0 src.density = 0 walk_to(src,0) - src.visible_message("[src] dies!") + src.visible_message("[src] [deathtext]") Harvest(var/obj/item/weapon/W, var/mob/living/user) diff --git a/code/modules/critters/critters.dm b/code/modules/critters/critters.dm index 9d86cb5bbe3..0ea545d6db6 100644 --- a/code/modules/critters/critters.dm +++ b/code/modules/critters/critters.dm @@ -242,3 +242,36 @@ atkcarbon = 1 atksilicon = 1 attacktext = "bites" + + + +// We can maybe make these controllable via some console or something +/obj/effect/critter/manhack + name = "viscerator" + desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations." + icon_state = "viscerator" + pass_flags = PASSTABLE + health = 15 + max_health = 15 + aggressive = 1 + opensdoors = 1 + defensive = 1 + wanderer = 1 + atkcarbon = 1 + atksilicon = 1 + atkmech = 1 + firevuln = 0 // immune to fire + brutevuln = 1 + ventcrawl = 1 + melee_damage_lower = 10 + melee_damage_upper = 15 + attacktext = "cuts" + attack_sound = 'bladeslice.wav' + chasestate = "viscerator_attack" + deathtext = "is smashed into pieces!" + + Die() + ..() + for(var/mob/O in viewers(src, null)) + O.show_message("\red [src] is smashed into pieces!", 1) + del(src) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ef89fa3218b..3560c5791f9 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -192,6 +192,24 @@ proc/isorgan(A) return copytext(sanitize(t),1,MAX_MESSAGE_LEN) +proc/Gibberish(t, p) + /* Turn text into complete gibberish! */ + var/returntext = "" + for(var/i = 1, i <= length(t), i++) + + var/letter = copytext(t, i, i+1) + if(prob(50)) + if(p >= 70) + letter = "" + + for(var/j = 1, j <= rand(0, 2), j++) + letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*") + + returntext += letter + + return returntext + + /proc/ninjaspeak(n) /* The difference with stutter is that this proc can stutter more than 1 letter diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi index 4d728bc847b99cd9764e2004ea9fda18d9b422f0..61f9cc096f87e60229f320e1e7da50a3865a99a7 100644 GIT binary patch delta 355 zcmV-p0i6D8DT?Vp<^yzbuiN7x?r;$qla>Y;-2 zc_p&J>d-(1#YSX}v8N_nKYYMopn`=z8}AkJc_A`w*+T`T$le)$JL92(LS))F{DcaM zyvz%cu^DWyp@Q{<Sq+?R4k&R2}b2(GYjhkY@V# zY|efm>u5t)EG>9xkfTCrkl!6q8tKodOcI$8n>5I?xxM_E+f;(mVc$lJ4(M9jpSlm< zFi{ts<&IBFzO~L(84lE8plF3LoTg_&)g-(-;`pvE)+@sp#y`MVIJJkV+ck!OY9{~k zK{8$&$(me3s3d=3b8(U+r|YyA;z&lv-sC?=EMa%t!uGHi-$td4SR+rL6ti*xI>EPf Bvl9RS delta 350 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