From d625d9c912b53fd73599283bdbbd67857b39ae31 Mon Sep 17 00:00:00 2001 From: cib Date: Sun, 6 May 2012 10:49:24 -0700 Subject: [PATCH 01/27] Started work on Meme. --- code/defines/procs/gamehelpers.dm | 6 ++ code/modules/mob/living/parasite/meme.dm | 98 ++++++++++++++++++++++++ code/modules/mob/living/say.dm | 3 + 3 files changed, 107 insertions(+) create mode 100644 code/modules/mob/living/parasite/meme.dm diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm index 63d66d9e4d4..94fe6844e7d 100644 --- a/code/defines/procs/gamehelpers.dm +++ b/code/defines/procs/gamehelpers.dm @@ -202,6 +202,12 @@ if(isInSight(source,C)) hear += C + // Parasites(e.g. Meme) + for(var/mob/living/carbon/C in V) + for(var/mob/M in C.parasites) + hear += M + world << "[M] added to hearers" + /* -- Handled above. WHY IS THIS HERE? WHYYYYYYY // Personal AIs for(var/obj/item/device/paicard/C in V) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm new file mode 100644 index 00000000000..8c27447b005 --- /dev/null +++ b/code/modules/mob/living/parasite/meme.dm @@ -0,0 +1,98 @@ +// === MEMETIC ANOMALY === +// ======================= + +/** +This life form is a form of parasite that can gain a certain level of control +over its host. Its player will share vision and hearing with the host, and it'll +be able to influence the host through various commands. +**/ + + +// === PARASITE === +// ================ + +// a list of all the parasites in the mob +mob/living/carbon/var/list/parasites = list() + +mob/living/parasite + var + mob/living/carbon/host // the host that this parasite occupies + + Login() + ..() + + // make the client see through the host instead + client.eye = host + client.perspective = EYE_PERSPECTIVE + +mob/living/parasite/proc/enter_host(mob/living/carbon/host) + // by default, parasites can't share a body with other life forms + if(host.parasites.len > 0) + return 0 + + src.host = host + + if(client) client.eye = host + + return 1 + +mob/living/parasite/proc/exit_host() + src.host.parasites.Remove(src) + src.host = null + + return 1 + + +// === MEME === +// ============ + +// Memes use points for many actions +mob/living/parasite/meme/var/meme_points = 100 + +mob/living/parasite/meme/Life() + ..() + // recover meme points slowly + meme_points += 1 + +// When a meme speaks, it speaks through its host +mob/living/parasite/meme/say(message as text) + world << "Trying to speak" + if(!host) + usr << "\red You can't speak without host!" + return + + world << "[host] should now say [message]" + + host.say(message) + usr = host + return host.say(message) + +mob/living/parasite/meme/whisper(message as text) + if(!host) + usr << "\red You can't speak without host!" + return + + + return host.whisper(message) + +mob/living/parasite/meme/me_verb(message as text) + set name = "Me" + if(!host) + usr << "\red You can't emote without host!" + return + + return host.me_verb(message) + +// A meme understands everything their host understands +mob/living/parasite/meme/say_understands(mob/other) + if(!host) return 0 + + return host.say_understands(other) + + +// TEST CODE +client/verb/become_meme(target as mob in world) + var/mob/living/parasite/meme/M = new + M.enter_host(target) + src.mob = M +// END TEST CODE \ No newline at end of file diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 1c459ef1769..4d40f85c005 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -338,7 +338,9 @@ */ + world << "getting listeners" listening = get_mobs_in_view(message_range, src) + world << "done getting listeners" for(var/mob/M in world) if (!M.client) continue //skip monkeys and leavers @@ -515,6 +517,7 @@ for (var/mob/M in heard_b) M.show_message(rendered, 2) M << speech_bubble + world << "[M] heard" spawn(30) del(speech_bubble) /* From e408cad9674ac731b856c72652bede6034983140 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 12 May 2012 21:41:56 +0200 Subject: [PATCH 02/27] Fixed a bug where memes wouldn't be added to their host's parasite list. --- code/defines/procs/gamehelpers.dm | 1 - code/modules/mob/living/parasite/meme.dm | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm index 94fe6844e7d..60d344c138e 100644 --- a/code/defines/procs/gamehelpers.dm +++ b/code/defines/procs/gamehelpers.dm @@ -206,7 +206,6 @@ for(var/mob/living/carbon/C in V) for(var/mob/M in C.parasites) hear += M - world << "[M] added to hearers" /* -- Handled above. WHY IS THIS HERE? WHYYYYYYY // Personal AIs diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 8c27447b005..ff6c693ed2e 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -31,6 +31,7 @@ mob/living/parasite/proc/enter_host(mob/living/carbon/host) return 0 src.host = host + host.parasites.Add(src) if(client) client.eye = host @@ -49,6 +50,9 @@ mob/living/parasite/proc/exit_host() // Memes use points for many actions mob/living/parasite/meme/var/meme_points = 100 +// Memes have a list of indoctrinated hosts +mob/living/parasite/meme/var/list/indoctrinated = list() + mob/living/parasite/meme/Life() ..() // recover meme points slowly @@ -89,6 +93,8 @@ mob/living/parasite/meme/say_understands(mob/other) return host.say_understands(other) +// A meme can make people hear things with the thought ability + // TEST CODE client/verb/become_meme(target as mob in world) From c7cfe85ad570f3261af0767c815818e21c24f476 Mon Sep 17 00:00:00 2001 From: cib Date: Mon, 14 May 2012 17:36:00 +0200 Subject: [PATCH 03/27] More work on Meme verbs. --- code/modules/mob/living/parasite/meme.dm | 195 ++++++++++++++++++++++- code/modules/mob/living/say.dm | 4 - 2 files changed, 188 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index ff6c693ed2e..dfeb3e7ca1b 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -7,6 +7,9 @@ over its host. Its player will share vision and hearing with the host, and it'll be able to influence the host through various commands. **/ +// The maximum amount of points a meme can gather. +var/global/const/MAXIMUM_MEME_POINTS = 500 + // === PARASITE === // ================ @@ -25,6 +28,7 @@ mob/living/parasite client.eye = host client.perspective = EYE_PERSPECTIVE + mob/living/parasite/proc/enter_host(mob/living/carbon/host) // by default, parasites can't share a body with other life forms if(host.parasites.len > 0) @@ -56,29 +60,25 @@ mob/living/parasite/meme/var/list/indoctrinated = list() mob/living/parasite/meme/Life() ..() // recover meme points slowly - meme_points += 1 + meme_points = min(meme_points + 1, MAXIMUM_MEME_POINTS) // When a meme speaks, it speaks through its host mob/living/parasite/meme/say(message as text) - world << "Trying to speak" if(!host) usr << "\red You can't speak without host!" return - world << "[host] should now say [message]" - - host.say(message) - usr = host return host.say(message) +// Same as speak, just with whisper mob/living/parasite/meme/whisper(message as text) if(!host) usr << "\red You can't speak without host!" return - return host.whisper(message) +// Make the host do things mob/living/parasite/meme/me_verb(message as text) set name = "Me" if(!host) @@ -93,7 +93,188 @@ mob/living/parasite/meme/say_understands(mob/other) return host.say_understands(other) +// Try to use amount points, return 1 if successful +mob/living/parasite/meme/proc/use_points(amount) + if(src.meme_points < amount) + src << "* You don't have enough meme points(need [amount])." + return 0 + + src.meme_points -= round(amount) + return 1 + +// Let the meme choose one of his indoctrinated mobs as target +mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message) + var/list/candidates = indoctrinated.Copy() + candidates.Add(src.host) + + var/mob/target = null + if(candidates.len == 1) + target = candidates[1] + else + target = input(message,title) as null|mob in candidates + + return target + + // A meme can make people hear things with the thought ability +mob/living/parasite/meme/verb/Thought() + set category = "Meme" + + if(meme_points < 150) + // just call use_points() to give the standard failure message + use_points(150) + return + + var/list/candidates = indoctrinated.Copy() + candidates.Add(src.host) + + var/mob/target = select_indoctrinated("Thought", "Select a target which will hear your thought.") + + if(!target) return + + var/speaker = input("Select the voice in which you would like to make yourself heard.", "Voice") as null|text + if(!speaker) return + + var/message = input("What would you like to say?", "Message") as null|text + if(!message) return + + // Use the points at the end rather than the beginning, because the user might cancel + if(!use_points(150)) return + + var/rendered = "[speaker] [message]" + target.show_message(rendered) + + usr << "You make [target] hear: [rendered]" + + +// Cause great agony with the host, used for conditioning the host +mob/living/parasite/meme/verb/Agony() + set category = "Meme" + + if(!src.host) return + if(!use_points(200)) return + + spawn + // backup the host incase we switch hosts after using the verb + var/mob/host = src.host + + host.paralysis = max(host.paralysis, 2) + + host.flash_pain() + host << "\red You feel excrutiating pain all over your body! It is so bad you can't think or articulate yourself properly.." + + usr << "You send a jolt of agonizing pain through [host], they should be unable to concentrate on anything else for half a minute." + + host.emote("scream") + + for(var/i=0, i<10, i++) + sleep(20) + if(prob(50)) host.flash_pain() + if(prob(10)) host.paralysis = max(host.paralysis, 2) + if(prob(15)) host.emote("twitch") + else if(prob(15)) host.emote("scream") + else if(prob(10)) host.emote("collapse") + + if(i == 10) + host << "\red THE PAIN! AGHH, THE PAIN! MAKE IT STOP! ANYTHING TO MAKE IT STOP!" + + host << "\red The pain subsides.." + +// Cause great joy with the host, used for conditioning the host +mob/living/parasite/meme/verb/Joy() + set category = "Meme" + + if(!src.host) return + if(!use_points(200)) return + + spawn + var/mob/host = target + host.druggy = max(host.druggy, 5) + host.slurring = max(host.slurring, 10) + + usr << "You stimulate [host.name]'s brain, injecting waves of endorphines and dopamine into the tissue. They should now forget all their worries, particularly relating to you, for around a minute." + + host << "\red You are feeling wonderful! Your head is numb and drowsy, and you can't help forgetting all the worries in the world." + + while(host.druggy > 0) + sleep(10) + + host << "\red You are feeling clear-headed again.." + +// Cause the target to hallucinate. +mob/living/parasite/meme/verb/Hallucinate() + set category = "Meme" + + if(!src.host) return + if(!use_points(300)) return + + var/mob/target = select_indoctrinated("Hallucination", "Who should hallucinate?") + + target.hallucination += 100 + + usr << "You make [target] hallucinate." + +mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob in world) + set category = "Meme" + + if(!istype(target, /mob/living/carbon/human)) + src << "You can't jump to this creature.." + return + if(!(target in view(1, host))) + src << "The target is not close enough." + return + + // Find out whether we can speak + if (host.silent || host.stat || (host.disabilities & 64)) + src << "Your host can't speak.." + return + + if(!use_points(350)) return + + for(var/mob/M in view(1, host)) + M.show_message("[host] whispers something incoherent.",2) // 2 stands for hearable message + + // Find out whether the target can hear + if(target.disabilities & 32 || target.ear_deaf) + src << "Your target doesn't seem to hear you.." + return + + src.exit_host() + src.enter_host(target) + + usr << "You successfully jumped to [target]." + +mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world) + set category = "Meme" + + if(!istype(target, /mob/living/carbon/human)) + src << "You can't jump to this creature.." + return + if(!(target in view(host))) + src << "The target is not close enough." + return + + // Find out whether we can speak + if (host.silent || host.stat || (host.disabilities & 64)) + src << "Your host can't speak.." + return + + if(!use_points(500)) return + + for(var/mob/M in view(host)) + M.show_message("[host] screams something incoherent!",2) // 2 stands for hearable message + + // Find out whether the target can hear + if(target.disabilities & 32 || target.ear_deaf) + src << "Your target doesn't seem to hear you.." + return + + src.exit_host() + src.enter_host(target) + + usr << "You successfully jumped to [target]." + + // TEST CODE diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 4d40f85c005..7eac78b9547 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -337,10 +337,7 @@ listening|=M */ - - world << "getting listeners" listening = get_mobs_in_view(message_range, src) - world << "done getting listeners" for(var/mob/M in world) if (!M.client) continue //skip monkeys and leavers @@ -517,7 +514,6 @@ for (var/mob/M in heard_b) M.show_message(rendered, 2) M << speech_bubble - world << "[M] heard" spawn(30) del(speech_bubble) /* From cbc88f16a0ea77ce8d1af35c1ad0bab4bf3469f5 Mon Sep 17 00:00:00 2001 From: cib Date: Mon, 14 May 2012 18:00:00 +0200 Subject: [PATCH 04/27] Forgot to commit the .dme --- baystation12.dme | 1 + code/modules/mob/living/parasite/meme.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/baystation12.dme b/baystation12.dme index d007fb1cced..891bcea5c67 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -119,6 +119,7 @@ #define FILE_DIR "code/modules/mob/living/carbon/human" #define FILE_DIR "code/modules/mob/living/carbon/metroid" #define FILE_DIR "code/modules/mob/living/carbon/monkey" +#define FILE_DIR "code/modules/mob/living/parasite" #define FILE_DIR "code/modules/mob/living/silicon" #define FILE_DIR "code/modules/mob/living/silicon/ai" #define FILE_DIR "code/modules/mob/living/silicon/decoy" diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index dfeb3e7ca1b..cfac4c04d4f 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -188,7 +188,7 @@ mob/living/parasite/meme/verb/Joy() if(!use_points(200)) return spawn - var/mob/host = target + var/mob/host = src.host host.druggy = max(host.druggy, 5) host.slurring = max(host.slurring, 10) From c5bb020a3131815081c16a3b4d6634a439b668c0 Mon Sep 17 00:00:00 2001 From: cib Date: Mon, 14 May 2012 20:27:55 +0200 Subject: [PATCH 05/27] Fine-tuned meme verbs a bit. --- code/modules/mob/living/parasite/meme.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index cfac4c04d4f..c20f3341bc6 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -141,6 +141,7 @@ mob/living/parasite/meme/verb/Thought() // Use the points at the end rather than the beginning, because the user might cancel if(!use_points(150)) return + message = say_quote(message) var/rendered = "[speaker] [message]" target.show_message(rendered) @@ -168,7 +169,7 @@ mob/living/parasite/meme/verb/Agony() host.emote("scream") for(var/i=0, i<10, i++) - sleep(20) + sleep(50) if(prob(50)) host.flash_pain() if(prob(10)) host.paralysis = max(host.paralysis, 2) if(prob(15)) host.emote("twitch") @@ -189,7 +190,7 @@ mob/living/parasite/meme/verb/Joy() spawn var/mob/host = src.host - host.druggy = max(host.druggy, 5) + host.druggy = max(host.druggy, 50) host.slurring = max(host.slurring, 10) usr << "You stimulate [host.name]'s brain, injecting waves of endorphines and dopamine into the tissue. They should now forget all their worries, particularly relating to you, for around a minute." @@ -220,7 +221,7 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i if(!istype(target, /mob/living/carbon/human)) src << "You can't jump to this creature.." return - if(!(target in view(1, host))) + if(!(target in view(1, host)+src)) src << "The target is not close enough." return @@ -261,7 +262,7 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob if(!use_points(500)) return - for(var/mob/M in view(host)) + for(var/mob/M in view(host)+src) M.show_message("[host] screams something incoherent!",2) // 2 stands for hearable message // Find out whether the target can hear From 05f3330b0c1e58aea48de2bb1c2bd80b767fdc34 Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 13:46:19 +0200 Subject: [PATCH 06/27] Added more meme abilities. --- code/defines/mob/living/carbon/carbon.dm | 3 + code/modules/mob/living/carbon/human/human.dm | 2 + code/modules/mob/living/carbon/human/life.dm | 7 +++ code/modules/mob/living/carbon/shock.dm | 2 + code/modules/mob/living/parasite/meme.dm | 55 +++++++++++++++++++ code/modules/mob/organ/pain.dm | 2 + 6 files changed, 71 insertions(+) diff --git a/code/defines/mob/living/carbon/carbon.dm b/code/defines/mob/living/carbon/carbon.dm index 7715ce30bfb..504be351276 100644 --- a/code/defines/mob/living/carbon/carbon.dm +++ b/code/defines/mob/living/carbon/carbon.dm @@ -12,5 +12,8 @@ var/list/datum/disease2/disease/resistances2 = list() var/antibodies = 0 + var/analgesic = 0 // when this is set, the mob isn't affected by shock or pain + // life should decrease this by 1 every tick + mob var/list/disease_symptoms = 0 // a list of disease-incurred symptoms \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 60acabcabaf..2f1a091aba8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -270,6 +270,8 @@ if(reagents.has_reagent("nuka_cola")) return -1 + if(analgesic) return -1 + if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything var/health_deficiency = traumatic_shock diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d68b0c714d5..a0cc50e1d58 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -133,6 +133,9 @@ proc handle_health_updates() + // the analgesic effect wears off slowly + analgesic = max(0, analgesic - 1) + // if the mob has enough health, she should slowly heal if(stat == 1) if(health >= 0) @@ -151,6 +154,8 @@ lying = 1 //Seriously, stay down :x update_clothing() + + clamp_values() SetStunned(min(stunned, 20)) @@ -1446,6 +1451,8 @@ handle_shock() ..() + if(analgesic) return // analgesic avoids all traumatic shock temporarily + if(health < 0) // health 0 makes you immediately collapse shock_stage = max(shock_stage, 61) diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index f53ca6f66f0..e1b9d6c90c5 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -14,6 +14,8 @@ src.traumatic_shock -= 200 // make synaptizine function as good painkiller if(src.slurring) src.traumatic_shock -= 20 + if(src.analgesic) + src.traumatic_shock = 0 // broken or ripped off organs will add quite a bit of pain if(istype(src,/mob/living/carbon/human)) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index c20f3341bc6..d36d08859ae 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -215,6 +215,7 @@ mob/living/parasite/meme/verb/Hallucinate() usr << "You make [target] hallucinate." +// Jump to a closeby target through a whisper mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob in world) set category = "Meme" @@ -245,6 +246,7 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i usr << "You successfully jumped to [target]." +// Jump to a distant target through a shout mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world) set category = "Meme" @@ -275,6 +277,59 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob usr << "You successfully jumped to [target]." +// ATTUNE a mob, adding it to the indoctrinated list +mob/living/parasite/meme/verb/Attune() + set category = "Meme" + + if(host in src.indoctrinated) + usr << "You have already attuned this host." + return + + if(!host) return + if(!use_points(400)) return + + src.indoctrinated.Add(host) + + usr << "You successfully indoctrinated [host]." + +// Enables the mob to take a lot more damage +mob/living/parasite/meme/verb/Analgesic() + set category = "Meme" + + if(!host) return + if(!use_points(500)) return + + usr << "You inject drugs into [host]." + host << "\red You feel your body strengthen and your pain subside.." + host.analgesic = 60 + while(host.analgesic > 0) + sleep(10) + host << "\red The dizziness wears off, and you can feel pain again.." + + +// Take control of the mob +mob/living/parasite/meme/verb/Possession() + set category = "Meme" + + if(!host) return + if(!use_points(500)) return + + usr << "You take control of [host]!" + host << "\red Everything goes black.." + + spawn + var/client/host_client = host.client + var/client/meme_client = src.client + + if(host_client) host_client.mob = null + meme_client.mob = host + + sleep(300) + + if(host_client) host_client.mob = host + if(meme_client) meme_client.mob = src + src << "\red You lose control.." + diff --git a/code/modules/mob/organ/pain.dm b/code/modules/mob/organ/pain.dm index fb0715138c3..21825ce8eaa 100644 --- a/code/modules/mob/organ/pain.dm +++ b/code/modules/mob/organ/pain.dm @@ -38,6 +38,8 @@ mob/living/carbon/human/proc/handle_pain() return if(reagents.has_reagent("oxycodone")) return + if(analgesic) + return var/maxdam = 0 var/datum/organ/external/damaged_organ = null for(var/name in organs) From 5bd2508fbcfa1ed378b08349a3884925f1ff4502 Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 16:31:40 +0200 Subject: [PATCH 07/27] Added Meme weaknesses, added more Meme verbs. --- code/game/objects/devices/flash.dm | 5 + code/modules/mob/living/carbon/human/emote.dm | 4 + code/modules/mob/living/parasite/meme.dm | 145 +++++++++++++++++- code/modules/mob/living/say.dm | 4 + code/modules/mob/mob_defines.dm | 1 + 5 files changed, 151 insertions(+), 8 deletions(-) diff --git a/code/game/objects/devices/flash.dm b/code/game/objects/devices/flash.dm index 9aee8fb1b7a..3508f652fc9 100644 --- a/code/game/objects/devices/flash.dm +++ b/code/game/objects/devices/flash.dm @@ -75,6 +75,11 @@ flick("e_flash", M.flash) if(ishuman(M) && ishuman(user) && M.stat!=DEAD) + // kill all memes + for(var/mob/living/parasite/meme/P in M:parasites) + P << "\red The bright flash is unbearable.. You lose consciousness and fade away.." + P.death() + if(user.mind && user.mind in ticker.mode.head_revolutionaries) var/revsafe = 0 for(var/obj/item/weapon/implant/loyalty/L in M) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index dab1a9412f6..fcdc76a3bbd 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,6 +1,10 @@ /mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null) var/param = null + if(!emote_allowed && usr == src) + usr << "You are unable to emote." + return + if (findtext(act, " ", 1, null)) var/t1 = findtext(act, " ", 1, null) param = copytext(act, t1 + 1, length(act) + 1) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index d36d08859ae..19ac6cbeb8d 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -53,17 +53,50 @@ mob/living/parasite/proc/exit_host() // Memes use points for many actions mob/living/parasite/meme/var/meme_points = 100 +mob/living/parasite/meme/var/dormant = 0 // Memes have a list of indoctrinated hosts mob/living/parasite/meme/var/list/indoctrinated = list() mob/living/parasite/meme/Life() ..() + // recover meme points slowly - meme_points = min(meme_points + 1, MAXIMUM_MEME_POINTS) + var/gain = 1 + if(dormant) gain = 3 // dormant recovers points faster + + meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS) + + if(host) + // if there are sleep toxins in the host's body, that's bad + if(host.reagents.has_reagent("stoxin")) + src << "\red Something in your host's blood makes you lose consciousness.. you fade away.." + src.death() + return + // a host without brain is no good + if(!host.mind) + src << "\red Your host has no mind.. you fade away.." + src.death() + return + if(host.stat == 2) + src << "\red Your host has died.. you fade away.." + src.death() + return + + if(host.blinded) src.blinded = 1 + else src.blinded = 0 + + +mob/living/parasite/meme/death() + // make sure the mob is on the actual map before gibbing + if(host) src.loc = host.loc + return ..(1) // When a meme speaks, it speaks through its host mob/living/parasite/meme/say(message as text) + if(dormant) + usr << "\red You're dormant!" + return if(!host) usr << "\red You can't speak without host!" return @@ -72,6 +105,9 @@ mob/living/parasite/meme/say(message as text) // Same as speak, just with whisper mob/living/parasite/meme/whisper(message as text) + if(dormant) + usr << "\red You're dormant!" + return if(!host) usr << "\red You can't speak without host!" return @@ -81,6 +117,12 @@ mob/living/parasite/meme/whisper(message as text) // Make the host do things mob/living/parasite/meme/me_verb(message as text) set name = "Me" + + + if(dormant) + usr << "\red You're dormant!" + return + if(!host) usr << "\red You can't emote without host!" return @@ -95,6 +137,9 @@ mob/living/parasite/meme/say_understands(mob/other) // Try to use amount points, return 1 if successful mob/living/parasite/meme/proc/use_points(amount) + if(dormant) + usr << "\red You're dormant!" + return if(src.meme_points < amount) src << "* You don't have enough meme points(need [amount])." return 0 @@ -104,7 +149,15 @@ mob/living/parasite/meme/proc/use_points(amount) // Let the meme choose one of his indoctrinated mobs as target mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message) - var/list/candidates = indoctrinated.Copy() + var/list/candidates + + // Can only affect other mobs thant he host if not blinded + if(blinded) + candidates = list() + src << "\red You are blinded, so you can not affect mobs other than your host." + else + candidates = indoctrinated.Copy() + candidates.Add(src.host) var/mob/target = null @@ -147,6 +200,57 @@ mob/living/parasite/meme/verb/Thought() usr << "You make [target] hear: [rendered]" +// Mutes the host +mob/living/parasite/meme/verb/Mute() + set category = "Meme" + + if(!src.host) return + if(!host.speech_allowed) + usr << "\red Your host already can't speak.." + return + if(!use_points(250)) return + + spawn + // backup the host incase we switch hosts after using the verb + var/mob/host = src.host + + host << "\red Your tongue feels numb.. You lose your ability to speak." + usr << "\red Your host can't speak anymore." + + host.speech_allowed = 0 + + sleep(1200) + + host.speech_allowed = 1 + host << "\red Your tongue has feeling again.." + usr << "\red [host] can speak again." + +// Makes the host unable to emote +mob/living/parasite/meme/verb/Paralyze() + set category = "Meme" + + if(!src.host) return + if(!host.emote_allowed) + usr << "\red Your host already can't use body language.." + return + if(!use_points(250)) return + + spawn + // backup the host incase we switch hosts after using the verb + var/mob/host = src.host + + host << "\red Your body feels numb.. You lose your ability to use body language." + usr << "\red Your host can't use body language anymore." + + host.emote_allowed = 0 + + sleep(1200) + + host.emote_allowed = 1 + host << "\red Your body has feeling again.." + usr << "\red [host] can use body language again." + + // Cause great agony with the host, used for conditioning the host mob/living/parasite/meme/verb/Agony() @@ -219,7 +323,7 @@ mob/living/parasite/meme/verb/Hallucinate() mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob in world) set category = "Meme" - if(!istype(target, /mob/living/carbon/human)) + if(!istype(target, /mob/living/carbon/human) || !target.mind) src << "You can't jump to this creature.." return if(!(target in view(1, host)+src)) @@ -227,7 +331,7 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i return // Find out whether we can speak - if (host.silent || host.stat || (host.disabilities & 64)) + if (host.silent || (host.disabilities & 64)) src << "Your host can't speak.." return @@ -250,7 +354,7 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world) set category = "Meme" - if(!istype(target, /mob/living/carbon/human)) + if(!istype(target, /mob/living/carbon/human) || !target.mind) src << "You can't jump to this creature.." return if(!(target in view(host))) @@ -258,7 +362,7 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob return // Find out whether we can speak - if (host.silent || host.stat || (host.disabilities & 64)) + if (host.silent || (host.disabilities & 64)) src << "Your host can't speak.." return @@ -297,6 +401,9 @@ mob/living/parasite/meme/verb/Analgesic() set category = "Meme" if(!host) return + if(!(host in indoctrinated)) + usr << "\red You need to attune the host first." + return if(!use_points(500)) return usr << "You inject drugs into [host]." @@ -312,25 +419,47 @@ mob/living/parasite/meme/verb/Possession() set category = "Meme" if(!host) return + if(!(host in indoctrinated)) + usr << "\red You need to attune the host first." + return if(!use_points(500)) return usr << "You take control of [host]!" host << "\red Everything goes black.." spawn + var/mob/dummy = new var/client/host_client = host.client var/client/meme_client = src.client - if(host_client) host_client.mob = null + if(host_client) host_client.mob = dummy meme_client.mob = host - sleep(300) + sleep(600) if(host_client) host_client.mob = host if(meme_client) meme_client.mob = src src << "\red You lose control.." + del dummy +// Enter dormant mode, increases meme point gain +mob/living/parasite/meme/verb/Dormant() + set category = "Meme" + + if(!host) return + if(!use_points(100)) return + + usr << "You enter dormant mode.. You won't be able to take action until all your points have recharged." + + dormant = 1 + + while(meme_points < 500) + sleep(10) + + dormant = 0 + + usr << "\red You have regained all points and exited dormant mode!" // TEST CODE diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 73b20cc951f..1e9cb3248a3 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -32,6 +32,10 @@ var/message_old = message message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + if(!speech_allowed && usr == src) + usr << "\red You can't speak." + return + if (!message) return diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index a7d4ec9ac9c..c74eb9bf36a 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -70,6 +70,7 @@ var/obj/screen/zone_sel/zone_sel = null var/emote_allowed = 1 + var/speech_allowed = 1 var/computer_id = null var/lastattacker = null var/lastattacked = null From 3bf3669ffbd023b1f8f051ad87aebb022350b17e Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 18:54:26 +0200 Subject: [PATCH 08/27] This should enable pAIs and parasites to see emotes. --- code/modules/mob/living/carbon/human/emote.dm | 4 ++-- code/modules/mob/living/parasite/meme.dm | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index fcdc76a3bbd..0e45f878857 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -537,8 +537,8 @@ if (m_type & 1) - for (var/mob/O in viewers(src, null)) + for (var/mob/O in world) if(O.client && (O.client.eye in viewers(src.loc))) O.show_message(message, m_type) else if (m_type & 2) - for (var/mob/O in hearers(src.loc, null)) + for (var/mob/O in world) if(O.client && (O.client.eye in hearers(src.loc))) O.show_message(message, m_type) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 19ac6cbeb8d..3bb642cd325 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -429,16 +429,16 @@ mob/living/parasite/meme/verb/Possession() spawn var/mob/dummy = new - var/client/host_client = host.client - var/client/meme_client = src.client + var/client/host_key = host.key + var/client/meme_key = src.key - if(host_client) host_client.mob = dummy - meme_client.mob = host + if(host_client) dummy.key = host_key + host.key = meme_key sleep(600) - if(host_client) host_client.mob = host - if(meme_client) meme_client.mob = src + host.key = host_key + src.key = meme_key src << "\red You lose control.." del dummy From e81316a2d40bc089cb8648a2d7586c6b97023388 Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 19:14:56 +0200 Subject: [PATCH 09/27] mend --- baystation12.dme | 1 + code/modules/mob/living/parasite/meme.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/baystation12.dme b/baystation12.dme index 891bcea5c67..2c937cff3be 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -987,6 +987,7 @@ #include "code\modules\mob\living\carbon\monkey\npc.dm" #include "code\modules\mob\living\carbon\monkey\powers.dm" #include "code\modules\mob\living\carbon\monkey\say.dm" +#include "code\modules\mob\living\parasite\meme.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\say.dm" #include "code\modules\mob\living\silicon\silicon.dm" diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 3bb642cd325..9cd33357d3e 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -432,7 +432,7 @@ mob/living/parasite/meme/verb/Possession() var/client/host_key = host.key var/client/meme_key = src.key - if(host_client) dummy.key = host_key + dummy.key = host_key host.key = meme_key sleep(600) From a740a14fd4d5839963932a410c59124dfd3e40ca Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 19:58:13 +0200 Subject: [PATCH 10/27] Fixed a runtime. --- code/modules/mob/living/parasite/meme.dm | 31 ++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 9cd33357d3e..773edd2aaff 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -61,27 +61,28 @@ mob/living/parasite/meme/var/list/indoctrinated = list() mob/living/parasite/meme/Life() ..() + if(!host) return + // recover meme points slowly var/gain = 1 if(dormant) gain = 3 // dormant recovers points faster meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS) - if(host) - // if there are sleep toxins in the host's body, that's bad - if(host.reagents.has_reagent("stoxin")) - src << "\red Something in your host's blood makes you lose consciousness.. you fade away.." - src.death() - return - // a host without brain is no good - if(!host.mind) - src << "\red Your host has no mind.. you fade away.." - src.death() - return - if(host.stat == 2) - src << "\red Your host has died.. you fade away.." - src.death() - return + // if there are sleep toxins in the host's body, that's bad + if(host.reagents.has_reagent("stoxin")) + src << "\red Something in your host's blood makes you lose consciousness.. you fade away.." + src.death() + return + // a host without brain is no good + if(!host.mind) + src << "\red Your host has no mind.. you fade away.." + src.death() + return + if(host.stat == 2) + src << "\red Your host has died.. you fade away.." + src.death() + return if(host.blinded) src.blinded = 1 else src.blinded = 0 From e2d5fd8de0ca37c22fa6b571d817a44b00d73183 Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 21:15:01 +0200 Subject: [PATCH 11/27] Fixed a bug with meme blindness. --- code/modules/mob/living/parasite/meme.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 773edd2aaff..9a04b1a7915 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -61,6 +61,10 @@ mob/living/parasite/meme/var/list/indoctrinated = list() mob/living/parasite/meme/Life() ..() + if(client) + if(blinded) client.eye = null + else client.eye = mob + if(!host) return // recover meme points slowly From ced7d810edce609478a778eab24e082c1d4b9e5d Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 21:49:00 +0200 Subject: [PATCH 12/27] mend --- code/modules/mob/living/parasite/meme.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 9a04b1a7915..99727ddf144 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -63,7 +63,7 @@ mob/living/parasite/meme/Life() if(client) if(blinded) client.eye = null - else client.eye = mob + else client.eye = host if(!host) return @@ -442,8 +442,8 @@ mob/living/parasite/meme/verb/Possession() sleep(600) - host.key = host_key src.key = meme_key + host.key = host_key src << "\red You lose control.." del dummy From 8f1be469188d44271711a3710dba50e52adba2a9 Mon Sep 17 00:00:00 2001 From: cib Date: Fri, 18 May 2012 23:38:32 +0200 Subject: [PATCH 13/27] Fixed a syntax error. --- code/modules/mob/living/carbon/human/emote.dm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 0e45f878857..66137de8578 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -537,8 +537,14 @@ if (m_type & 1) - for (var/mob/O in world) if(O.client && (O.client.eye in viewers(src.loc))) + for (var/mob/O in viewers(src, null)) + if(istype(O,/mob/living/carbon/human)) + for(var/mob/living/parasite/P in O:parasites) + P.show_message(message, m_type) O.show_message(message, m_type) else if (m_type & 2) - for (var/mob/O in world) if(O.client && (O.client.eye in hearers(src.loc))) + for (var/mob/O in hearers(src.loc, null)) + if(istype(O,/mob/living/carbon/human)) + for(var/mob/living/parasite/P in O:parasites) + P.show_message(message, m_type) O.show_message(message, m_type) From e31fde8c78749f169ac8e33d504bae1f021e09db Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 00:13:50 +0200 Subject: [PATCH 14/27] me_verb can now be called by someone other than the user. --- code/modules/mob/say.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index f8e9fb94320..04f1c747853 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -17,7 +17,7 @@ message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - usr.emote("me",1,message) + src.emote("me",1,message) /mob/proc/say_dead(var/message) var/name = src.real_name From 736738dbb4a5aefcf526e13d90712d681b71d67e Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 11:36:04 +0200 Subject: [PATCH 15/27] Fixed bug with meme death. --- code/modules/mob/living/parasite/meme.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 99727ddf144..34a4dc6c4e2 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -95,7 +95,9 @@ mob/living/parasite/meme/Life() mob/living/parasite/meme/death() // make sure the mob is on the actual map before gibbing if(host) src.loc = host.loc - return ..(1) + src.stat = 2 + ..() + del src // When a meme speaks, it speaks through its host mob/living/parasite/meme/say(message as text) From 19449f77b0f1dcda3f6189f84f627349add7dce5 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 14:38:52 +0200 Subject: [PATCH 16/27] Started work on the meme gamemode itself. --- code/game/gamemodes/game_mode.dm | 1 + code/game/gamemodes/meme/meme.dm | 155 +++++++++++++++++++++ code/game/gamemodes/newobjective.dm | 14 ++ code/modules/mob/living/parasite/meme.dm | 16 ++- code/modules/mob/new_player/preferences.dm | 1 + 5 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 code/game/gamemodes/meme/meme.dm diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 35232e6ab9c..278b5912329 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -253,6 +253,7 @@ Whitespace:Seperator;"} if(BE_WIZARD) roletext="wizard" if(BE_REV) roletext="revolutionary" if(BE_CULTIST) roletext="cultist" + if(BE_MEME) roletext="meme" for(var/mob/new_player/player in world) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm new file mode 100644 index 00000000000..39ac61d7aaa --- /dev/null +++ b/code/game/gamemodes/meme/meme.dm @@ -0,0 +1,155 @@ +/datum/game_mode/meme + name = "meme" + config_tag = "meme" + //required_players = 6 + required_players = 2 // for testing + restricted_jobs = list("AI", "Cyborg") + recommended_enemies = 2 // need at least a meme and a host + + + var + list/memes = list() + + var/datum/mind/first_host = null + const + prob_int_murder_target = 50 // intercept names the assassination target half the time + prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target + prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target + + prob_int_item = 50 // intercept names the theft target half the time + prob_right_item_l = 25 // lower bound on probability of naming right theft target + prob_right_item_h = 50 // upper bound on probability of naming the right theft target + + prob_int_sab_target = 50 // intercept names the sabotage target half the time + prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target + prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target + + prob_right_killer_l = 25 //lower bound on probability of naming the right operative + prob_right_killer_h = 50 //upper bound on probability of naming the right operative + prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly + prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly + + waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) + waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) + +/datum/game_mode/meme/announce() + world << "The current game mode is - Meme!" + world << "An unknown creature has infested the mind of a crew member. Find and destroy it by what means necessary." + +/datum/game_mode/meme/can_start() + if(!..()) + return 0 + + var/list/datum/mind/possible_memes = get_players_for_role(BE_MEME) + + if(possible_memes.len < 2) + log_admin("MODE FAILURE: MEME. NOT ENOUGH MEME CANDIDATES.") + return 0 // not enough candidates for meme + + var/datum/mind/meme = pick(possible_memes) + possible_memes.Remove(meme) + + first_host = pick(possible_memes) + + modePlayer += meme + modePlayer += first_host + + meme.assigned_role = "MODE" //So they aren't chosen for other jobs. + meme.special_role = "Meme" + + return 1 + +/datum/game_mode/meme/pre_setup() + return 1 + + +/datum/game_mode/meme/post_setup() + // create a meme and enter it + for(var/datum/mind/meme in memes) + var/mob/living/parasite/meme/M = new + meme.transfer_to(M) + M.enter_host(first_host) + break + + // TODO: make it possible to have multiple memes with multiple hosts + + spawn (rand(waittime_l, waittime_h)) + send_intercept() + ..() + return + + +/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme) + // meme always needs to attune X hosts + var/datum/objective/meme_attune/attune_objective = new + attune_objective.owner = meme + attune_objective.gen_amount_goal(3,6) + meme.objectives += attune_objective + + // generate some random objectives, use standard traitor objectives + var/job = first_host.assigned_role + + for(var/datum/objective/o in SelectObjectives(job, meme)) + o.owner = meme + meme.objectives += o + + return + +/datum/game_mode/proc/greet_meme(var/datum/mind/meme, var/you_are=1) + if (you_are) + meme.current << "\red You are a meme!" + + var/obj_count = 1 + for(var/datum/objective/objective in meme.objectives) + meme.current << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + return + +/datum/game_mode/meme/check_finished() + var/memes_alive = 0 + for(var/datum/mind/meme in memes) + if(!istype(meme.current,/mob/living/parasite/meme)) + continue + if(meme.current.stat==2) + continue + memes_alive++ + + if (memes_alive) + return ..() + else + return 1 + +/datum/game_mode/proc/auto_declare_completion_meme() + for(var/datum/mind/meme in memes) + var/memewin = 1 + var/meme_name + var/attuned = 0 + if((meme.current) && istype(meme.current,/mob/living/parasite/meme)) + meme_name = "[meme.key] (The Meme)" + world << "The meme was [meme.current.key]." + world << "The first host was [first_host.key]." + world << "The last host was [meme.current:host.key]." + world << "Hosts attuned: [attuned]" + + var/count = 1 + for(var/datum/objective/objective in meme.objectives) + if(objective.check_completion()) + world << "Objective #[count]: [objective.explanation_text] \green Success" + feedback_add_details("meme_objective","[objective.type]|SUCCESS") + else + world << "Objective #[count]: [objective.explanation_text] \red Failed" + feedback_add_details("meme_objective","[objective.type]|FAIL") + memewin = 0 + count++ + + else + meme_name = "[meme.key] (character destroyed)" + memewin = 0 + + if(memewin) + world << "The meme was successful!" + feedback_add_details("meme_success","SUCCESS") + else + world << "The meme has failed!" + feedback_add_details("meme_success","FAIL") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 5d92803d2f3..de5514ddd89 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -1226,6 +1226,20 @@ datum else return 0 + meme_attune + var/target_amount + proc/gen_amount_goal(var/lowbound = 4, var/highbound = 6) + target_amount = rand (lowbound,highbound) + + explanation_text = "Attune [target_amount] humanoid brains." + return target_amount + + check_completion() + if(owner && owner.current && istype(owner.current,/mob/living/parasite/meme) && (owner.current:indoctrinated.len >= target_amount)) + return 1 + else + return 0 + download var/target_amount proc/gen_amount_goal() diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 34a4dc6c4e2..53bf995f0db 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -468,10 +468,14 @@ mob/living/parasite/meme/verb/Dormant() usr << "\red You have regained all points and exited dormant mode!" +// Game mode helpers, used for theft objectives +// -------------------------------------------- +mob/living/parasite/check_contents_for(t) + if(!host) return 0 -// TEST CODE -client/verb/become_meme(target as mob in world) - var/mob/living/parasite/meme/M = new - M.enter_host(target) - src.mob = M -// END TEST CODE \ No newline at end of file + return host.check_contents_for(t) + +mob/living/parasite/check_contents_for_reagent(t) + if(!host) return 0 + + return host.check_contents_for_reagent(t) \ No newline at end of file diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm index 0c649035342..d1ecf5d15a5 100644 --- a/code/modules/mob/new_player/preferences.dm +++ b/code/modules/mob/new_player/preferences.dm @@ -39,6 +39,7 @@ var/const BE_CULTIST =(1<<7) BE_MONKEY =(1<<8) BE_PAI =(1<<9) + BE_MEME =(1<<10) From b941e407d1a318a595b20363ff350375ac1a78e8 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 14:42:41 +0200 Subject: [PATCH 17/27] Started work on the meme gamemode itself. --- code/modules/mob/new_player/preferences.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm index d1ecf5d15a5..dfd64aaf7e4 100644 --- a/code/modules/mob/new_player/preferences.dm +++ b/code/modules/mob/new_player/preferences.dm @@ -13,6 +13,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "pAI candidate" = 1, // -- TLE "cultist" = IS_MODE_COMPILED("cult"), "infested monkey" = IS_MODE_COMPILED("monkey"), + "meme" = IS_MODE_COMPILED("meme"), ) /* var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm --rastaf From a2e415edb3bed2b257fee4af8f7e72da438e0fa7 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 14:51:26 +0200 Subject: [PATCH 18/27] Fixed a few compile errors. --- baystation12.dme | 2 ++ code/game/gamemodes/meme/meme.dm | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 2c937cff3be..24a724f8d35 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -40,6 +40,7 @@ #define FILE_DIR "code/game/gamemodes/epidemic" #define FILE_DIR "code/game/gamemodes/extended" #define FILE_DIR "code/game/gamemodes/malfunction" +#define FILE_DIR "code/game/gamemodes/meme" #define FILE_DIR "code/game/gamemodes/meteor" #define FILE_DIR "code/game/gamemodes/nuclear" #define FILE_DIR "code/game/gamemodes/revolution" @@ -440,6 +441,7 @@ #include "code\game\gamemodes\extended\extended.dm" #include "code\game\gamemodes\malfunction\Malf_Modules.dm" #include "code\game\gamemodes\malfunction\malfunction.dm" +#include "code\game\gamemodes\meme\meme.dm" #include "code\game\gamemodes\meteor\meteor.dm" #include "code\game\gamemodes\meteor\meteors.dm" #include "code\game\gamemodes\nuclear\nuclear.dm" diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index 39ac61d7aaa..745c490bb57 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -1,5 +1,7 @@ +/datum/game_mode/var/list/memes = list() + /datum/game_mode/meme - name = "meme" + name = "Memetic Anomaly" config_tag = "meme" //required_players = 6 required_players = 2 // for testing @@ -8,7 +10,6 @@ var - list/memes = list() var/datum/mind/first_host = null const @@ -53,6 +54,7 @@ modePlayer += meme modePlayer += first_host + memes += meme meme.assigned_role = "MODE" //So they aren't chosen for other jobs. meme.special_role = "Meme" @@ -68,7 +70,8 @@ for(var/datum/mind/meme in memes) var/mob/living/parasite/meme/M = new meme.transfer_to(M) - M.enter_host(first_host) + M.enter_host(first_host.current) + forge_meme_objectives(meme, first_host) break // TODO: make it possible to have multiple memes with multiple hosts @@ -79,7 +82,7 @@ return -/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme) +/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme, var/datum/mind/first_host) // meme always needs to attune X hosts var/datum/objective/meme_attune/attune_objective = new attune_objective.owner = meme @@ -122,12 +125,10 @@ /datum/game_mode/proc/auto_declare_completion_meme() for(var/datum/mind/meme in memes) var/memewin = 1 - var/meme_name var/attuned = 0 if((meme.current) && istype(meme.current,/mob/living/parasite/meme)) - meme_name = "[meme.key] (The Meme)" world << "The meme was [meme.current.key]." - world << "The first host was [first_host.key]." + world << "The first host was [src:first_host.current.key]." world << "The last host was [meme.current:host.key]." world << "Hosts attuned: [attuned]" @@ -143,7 +144,6 @@ count++ else - meme_name = "[meme.key] (character destroyed)" memewin = 0 if(memewin) From e57851fbaf0af84cfe4874cdfcf09dc36e1a4617 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 16:47:09 +0200 Subject: [PATCH 19/27] Fixed a few bugs with meme. --- code/defines/procs/helpers.dm | 2 ++ code/game/gamemodes/meme/meme.dm | 2 ++ .../mob/living/carbon/human/whisper.dm | 4 +-- code/modules/mob/living/parasite/meme.dm | 25 ++++++++++++------- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 61dc65dbc3b..bae8943f02d 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -868,6 +868,8 @@ Turf and target are seperate in case you want to teleport some distance from a t temp_list.Add(M) for(var/mob/living/carbon/human/M in world) temp_list.Add(M) + for(var/mob/living/parasite/P in M.parasites) + temp_list.Add(P) for(var/mob/living/carbon/brain/M in world) temp_list.Add(M) for(var/mob/living/carbon/alien/M in world) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index 745c490bb57..988cc90d664 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -96,6 +96,8 @@ o.owner = meme meme.objectives += o + greet_meme() + return /datum/game_mode/proc/greet_meme(var/datum/mind/meme, var/you_are=1) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 2d5f675b973..a17d81795ef 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -62,11 +62,11 @@ if (O) O.hear_talk(src, message) - var/list/listening = hearers(message_range, src) + var/list/listening = get_mobs_in_view(message_range, src) // listening -= src // listening += src // WAT. - var/list/eavesdropping = hearers(2, src) + var/list/eavesdropping = get_mobs_in_view(message_range, src) eavesdropping -= src eavesdropping -= listening var/list/watching = hearers(5, src) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 53bf995f0db..f0b2ae61a4d 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -35,6 +35,7 @@ mob/living/parasite/proc/enter_host(mob/living/carbon/host) return 0 src.host = host + src.loc = host host.parasites.Add(src) if(client) client.eye = host @@ -44,6 +45,7 @@ mob/living/parasite/proc/enter_host(mob/living/carbon/host) mob/living/parasite/proc/exit_host() src.host.parasites.Remove(src) src.host = null + src.loc = null return 1 @@ -68,8 +70,8 @@ mob/living/parasite/meme/Life() if(!host) return // recover meme points slowly - var/gain = 1 - if(dormant) gain = 3 // dormant recovers points faster + var/gain = 2 + if(dormant) gain = 6 // dormant recovers points faster meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS) @@ -435,17 +437,17 @@ mob/living/parasite/meme/verb/Possession() host << "\red Everything goes black.." spawn - var/mob/dummy = new - var/client/host_key = host.key - var/client/meme_key = src.key + var/mob/living/dummy = new + var/datum/mind/host_mind = host.mind + var/datum/mind/meme_mind = src.mind - dummy.key = host_key - host.key = meme_key + host_mind.transfer_to(dummy) + meme_mind.transfer_to(host) sleep(600) - src.key = meme_key - host.key = host_key + meme_mind.transfer_to(src) + host_mind.transfer_to(host) src << "\red You lose control.." del dummy @@ -468,6 +470,11 @@ mob/living/parasite/meme/verb/Dormant() usr << "\red You have regained all points and exited dormant mode!" +mob/living/parasite/meme/verb/Show_Points() + set category = "Meme" + + usr << "Meme Points: [src.meme_points]/[MAXIMUM_MEME_POINTS]" + // Game mode helpers, used for theft objectives // -------------------------------------------- mob/living/parasite/check_contents_for(t) From 84d78fd2f0e198afbd51e76c5c1e9e377cce8972 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 17:52:18 +0200 Subject: [PATCH 20/27] Fixed a bug with possession. --- code/game/gamemodes/meme/meme.dm | 8 +++- code/modules/mob/living/parasite/meme.dm | 61 +++++++++++++++++++++++- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index 988cc90d664..b4e792fb195 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -69,9 +69,13 @@ // create a meme and enter it for(var/datum/mind/meme in memes) var/mob/living/parasite/meme/M = new + var/mob/original = meme.current meme.transfer_to(M) M.enter_host(first_host.current) forge_meme_objectives(meme, first_host) + + del original + break // TODO: make it possible to have multiple memes with multiple hosts @@ -96,7 +100,7 @@ o.owner = meme meme.objectives += o - greet_meme() + greet_meme(meme) return @@ -113,7 +117,7 @@ /datum/game_mode/meme/check_finished() var/memes_alive = 0 for(var/datum/mind/meme in memes) - if(!istype(meme.current,/mob/living/parasite/meme)) + if(!istype(meme.current,/mob/living)) continue if(meme.current.stat==2) continue diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index f0b2ae61a4d..0a62306778e 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -181,6 +181,8 @@ mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message) // A meme can make people hear things with the thought ability mob/living/parasite/meme/verb/Thought() set category = "Meme" + set name = "Thought(150)" + set desc = "Implants a thought into the target, making them think they heard someone talk." if(meme_points < 150) // just call use_points() to give the standard failure message @@ -212,6 +214,8 @@ mob/living/parasite/meme/verb/Thought() // Mutes the host mob/living/parasite/meme/verb/Mute() set category = "Meme" + set name = "Mute(250)" + set desc = "Prevents your host from talking for a while." if(!src.host) return if(!host.speech_allowed) @@ -237,6 +241,8 @@ mob/living/parasite/meme/verb/Mute() // Makes the host unable to emote mob/living/parasite/meme/verb/Paralyze() set category = "Meme" + set name = "Paralyze(250)" + set desc = "Prevents your host from using emote for a while." if(!src.host) return if(!host.emote_allowed) @@ -264,6 +270,8 @@ mob/living/parasite/meme/verb/Paralyze() // Cause great agony with the host, used for conditioning the host mob/living/parasite/meme/verb/Agony() set category = "Meme" + set name = "Agony(200)" + set desc = "Causes significant pain in your host." if(!src.host) return if(!use_points(200)) return @@ -283,7 +291,7 @@ mob/living/parasite/meme/verb/Agony() for(var/i=0, i<10, i++) sleep(50) - if(prob(50)) host.flash_pain() + if(prob(50)) host.flash_weak_pain() if(prob(10)) host.paralysis = max(host.paralysis, 2) if(prob(15)) host.emote("twitch") else if(prob(15)) host.emote("scream") @@ -297,6 +305,8 @@ mob/living/parasite/meme/verb/Agony() // Cause great joy with the host, used for conditioning the host mob/living/parasite/meme/verb/Joy() set category = "Meme" + set name = "Joy(200)" + set desc = "Causes significant joy in your host." if(!src.host) return if(!use_points(200)) return @@ -318,6 +328,8 @@ mob/living/parasite/meme/verb/Joy() // Cause the target to hallucinate. mob/living/parasite/meme/verb/Hallucinate() set category = "Meme" + set name = "Hallucinate(300)" + set desc = "Makes your host hallucinate, has a short delay." if(!src.host) return if(!use_points(300)) return @@ -331,6 +343,8 @@ mob/living/parasite/meme/verb/Hallucinate() // Jump to a closeby target through a whisper mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob in world) set category = "Meme" + set name = "Subtle Jump(350)" + set desc = "Move to a closeby human through a whisper." if(!istype(target, /mob/living/carbon/human) || !target.mind) src << "You can't jump to this creature.." @@ -362,6 +376,8 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i // Jump to a distant target through a shout mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world) set category = "Meme" + set name = "Obvious Jump(500)" + set desc = "Move to any mob in view through a shout." if(!istype(target, /mob/living/carbon/human) || !target.mind) src << "You can't jump to this creature.." @@ -390,9 +406,32 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob usr << "You successfully jumped to [target]." +// Jump to an attuned mob for free +mob/living/parasite/meme/verb/AttunedJump(mob/living/carbon/human/target as mob in world) + set category = "Meme" + set name = "Attuned Jump(0)" + set desc = "Move to a mob in sight that you have already attuned." + + if(!istype(target, /mob/living/carbon/human) || !target.mind) + src << "You can't jump to this creature.." + return + if(!(target in view(host))) + src << "You need to make eye-contact with the target." + return + if(!(target in indoctrinated)) + src << "You need to attune the target first." + return + + src.exit_host() + src.enter_host(target) + + usr << "You successfully jumped to [target]." + // ATTUNE a mob, adding it to the indoctrinated list mob/living/parasite/meme/verb/Attune() set category = "Meme" + set name = "Attune(400)" + set desc = "Change the host's brain structure, making it easier for you to manipulate him." if(host in src.indoctrinated) usr << "You have already attuned this host." @@ -408,6 +447,8 @@ mob/living/parasite/meme/verb/Attune() // Enables the mob to take a lot more damage mob/living/parasite/meme/verb/Analgesic() set category = "Meme" + set name = "Analgesic(500)" + set desc = "Combat drug that the host to move normally, even under life-threatening pain." if(!host) return if(!(host in indoctrinated)) @@ -423,9 +464,21 @@ mob/living/parasite/meme/verb/Analgesic() host << "\red The dizziness wears off, and you can feel pain again.." +mob/proc/clearHUD() + if(!hud_used) return + if(client) + client.screen -= hud_used.contents + client.screen -= hud_used.adding + client.screen -= hud_used.mon_blo + client.screen -= list( oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) + client.screen -= list( zone_sel, oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) + + // Take control of the mob mob/living/parasite/meme/verb/Possession() set category = "Meme" + set name = "Thought(500)" + set desc = "Take direct control of the host for a while." if(!host) return if(!(host in indoctrinated)) @@ -437,17 +490,21 @@ mob/living/parasite/meme/verb/Possession() host << "\red Everything goes black.." spawn - var/mob/living/dummy = new + var/mob/living/dummy = new(null) var/datum/mind/host_mind = host.mind var/datum/mind/meme_mind = src.mind host_mind.transfer_to(dummy) meme_mind.transfer_to(host) + host_mind.current.clearHUD() + host.update_clothing() sleep(600) meme_mind.transfer_to(src) host_mind.transfer_to(host) + meme_mind.current.clearHUD() + host.update_clothing() src << "\red You lose control.." del dummy From a571bffe8c31d0a837182839654780a0317b4ec5 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 19:08:40 +0200 Subject: [PATCH 21/27] Some bugfixes for meme. --- code/game/gamemodes/meme/meme.dm | 1 + code/modules/mob/living/parasite/meme.dm | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index b4e792fb195..af7a8f06224 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -71,6 +71,7 @@ var/mob/living/parasite/meme/M = new var/mob/original = meme.current meme.transfer_to(M) + M.clearHUD() M.enter_host(first_host.current) forge_meme_objectives(meme, first_host) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 0a62306778e..c1c9ab00325 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -8,7 +8,7 @@ be able to influence the host through various commands. **/ // The maximum amount of points a meme can gather. -var/global/const/MAXIMUM_MEME_POINTS = 500 +var/global/const/MAXIMUM_MEME_POINTS = 750 // === PARASITE === @@ -70,8 +70,8 @@ mob/living/parasite/meme/Life() if(!host) return // recover meme points slowly - var/gain = 2 - if(dormant) gain = 6 // dormant recovers points faster + var/gain = 4 + if(dormant) gain = 12 // dormant recovers points faster meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS) @@ -376,7 +376,7 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i // Jump to a distant target through a shout mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world) set category = "Meme" - set name = "Obvious Jump(500)" + set name = "Obvious Jump(750)" set desc = "Move to any mob in view through a shout." if(!istype(target, /mob/living/carbon/human) || !target.mind) @@ -391,7 +391,7 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob src << "Your host can't speak.." return - if(!use_points(500)) return + if(!use_points(750)) return for(var/mob/M in view(host)+src) M.show_message("[host] screams something incoherent!",2) // 2 stands for hearable message @@ -465,6 +465,7 @@ mob/living/parasite/meme/verb/Analgesic() mob/proc/clearHUD() + update_clothing() if(!hud_used) return if(client) client.screen -= hud_used.contents @@ -473,11 +474,10 @@ mob/proc/clearHUD() client.screen -= list( oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) client.screen -= list( zone_sel, oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) - // Take control of the mob mob/living/parasite/meme/verb/Possession() set category = "Meme" - set name = "Thought(500)" + set name = "Possession(500)" set desc = "Take direct control of the host for a while." if(!host) return @@ -490,7 +490,10 @@ mob/living/parasite/meme/verb/Possession() host << "\red Everything goes black.." spawn - var/mob/living/dummy = new(null) + var/mob/dummy = new() + dummy.loc = 0 + dummy.sight = BLIND + var/datum/mind/host_mind = host.mind var/datum/mind/meme_mind = src.mind @@ -512,6 +515,8 @@ mob/living/parasite/meme/verb/Possession() // Enter dormant mode, increases meme point gain mob/living/parasite/meme/verb/Dormant() set category = "Meme" + set name = "Dormant(100)" + set desc = "Speed up point recharging, will force you to cease all actions until all points are recharged." if(!host) return if(!use_points(100)) return From e9c4e4e5375b9e903b930d063c9ad1a110be0cb7 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 19:27:39 +0200 Subject: [PATCH 22/27] Updated changelog. --- html/changelog.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/html/changelog.html b/html/changelog.html index 1448218d8a1..e9647eebd2d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -47,6 +47,15 @@ Stuff which is in development and not yet visible to players or just code relate should be listed in the changelog upon commit though. Thanks. --> +
+

19 May 2012

+

cib updated:

+
    +
  • Implemented Memetic Anomaly game mode. A meme is a kind of parasite that can live in a human host and jump from player to player. They have traitor-like objectives, but must achieve them by controlling hosts, rather than doing it themselves.
  • +
  • Credits for the idea goes to: SCP-1312-1 . Playtesters: Erthilo, Cael_Aislin, AfterShave and critica.
  • +
+
+

13 May 2012

TG updated:

@@ -299,4 +308,4 @@ Credits Section

Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

- \ No newline at end of file + From 2693d7af717f2200f19778a578a0aed7885825f2 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 19:38:02 +0200 Subject: [PATCH 23/27] Another attempt to fix the HUD bug. --- code/modules/mob/living/parasite/meme.dm | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index c1c9ab00325..7a9061a18c2 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -466,13 +466,7 @@ mob/living/parasite/meme/verb/Analgesic() mob/proc/clearHUD() update_clothing() - if(!hud_used) return - if(client) - client.screen -= hud_used.contents - client.screen -= hud_used.adding - client.screen -= hud_used.mon_blo - client.screen -= list( oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) - client.screen -= list( zone_sel, oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) + if(client) client.screen.Cut() // Take control of the mob mob/living/parasite/meme/verb/Possession() @@ -525,7 +519,7 @@ mob/living/parasite/meme/verb/Dormant() dormant = 1 - while(meme_points < 500) + while(meme_points < MAXIMUM_MEME_POINTS) sleep(10) dormant = 0 From 548bcee177977543cf6f005b8e704f7f04b9452f Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 19:55:16 +0200 Subject: [PATCH 24/27] Fixed a bug where you could still whisper when meme-muted. Improved agony a bit. --- .../mob/living/carbon/human/whisper.dm | 4 ++++ code/modules/mob/living/parasite/meme.dm | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index a17d81795ef..c8c291131a2 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -11,6 +11,10 @@ src << "You are muted." return + if(!speech_allowed && usr == src) + usr << "\red You can't speak." + return + if (src.stat == 2) return src.say_dead(message) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index 7a9061a18c2..f56e9436f2f 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -173,7 +173,19 @@ mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message) if(candidates.len == 1) target = candidates[1] else - target = input(message,title) as null|mob in candidates + var/selected + + var/list/text_candidates = list() + var/list/map_text_to_mob = list() + + for(var/mob/living/carbon/human/M in candidates) + text_candidates += M.real_name + map_text_to_mob[M.real_name] = M + + selected = input(message,title) as null|mob in text_candidates + if(!selected) return null + + target = map_text_to_mob[selected] return target @@ -282,7 +294,7 @@ mob/living/parasite/meme/verb/Agony() host.paralysis = max(host.paralysis, 2) - host.flash_pain() + host.flash_weak_pain() host << "\red You feel excrutiating pain all over your body! It is so bad you can't think or articulate yourself properly.." usr << "You send a jolt of agonizing pain through [host], they should be unable to concentrate on anything else for half a minute." @@ -290,8 +302,9 @@ mob/living/parasite/meme/verb/Agony() host.emote("scream") for(var/i=0, i<10, i++) + host.stuttering = 2 sleep(50) - if(prob(50)) host.flash_weak_pain() + if(prob(80)) host.flash_weak_pain() if(prob(10)) host.paralysis = max(host.paralysis, 2) if(prob(15)) host.emote("twitch") else if(prob(15)) host.emote("scream") From d23da5e14954218555cabd4b4835e6c371ed32a3 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 21:01:01 +0200 Subject: [PATCH 25/27] Fixed a bug with meme target selection. --- code/modules/mob/living/parasite/meme.dm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm index f56e9436f2f..f0c219252fd 100644 --- a/code/modules/mob/living/parasite/meme.dm +++ b/code/modules/mob/living/parasite/meme.dm @@ -70,8 +70,8 @@ mob/living/parasite/meme/Life() if(!host) return // recover meme points slowly - var/gain = 4 - if(dormant) gain = 12 // dormant recovers points faster + var/gain = 3 + if(dormant) gain = 9 // dormant recovers points faster meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS) @@ -182,7 +182,7 @@ mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message) text_candidates += M.real_name map_text_to_mob[M.real_name] = M - selected = input(message,title) as null|mob in text_candidates + selected = input(message,title) as null|anything in text_candidates if(!selected) return null target = map_text_to_mob[selected] @@ -202,7 +202,8 @@ mob/living/parasite/meme/verb/Thought() return var/list/candidates = indoctrinated.Copy() - candidates.Add(src.host) + if(!(src.host in candidates)) + candidates.Add(src.host) var/mob/target = select_indoctrinated("Thought", "Select a target which will hear your thought.") @@ -211,7 +212,7 @@ mob/living/parasite/meme/verb/Thought() var/speaker = input("Select the voice in which you would like to make yourself heard.", "Voice") as null|text if(!speaker) return - var/message = input("What would you like to say?", "Message") as null|text + var/message = input("What would you like to say?", "Message") as null if(!message) return // Use the points at the end rather than the beginning, because the user might cancel @@ -344,11 +345,11 @@ mob/living/parasite/meme/verb/Hallucinate() set name = "Hallucinate(300)" set desc = "Makes your host hallucinate, has a short delay." - if(!src.host) return - if(!use_points(300)) return - var/mob/target = select_indoctrinated("Hallucination", "Who should hallucinate?") + if(!target) return + if(!use_points(300)) return + target.hallucination += 100 usr << "You make [target] hallucinate." @@ -456,6 +457,7 @@ mob/living/parasite/meme/verb/Attune() src.indoctrinated.Add(host) usr << "You successfully indoctrinated [host]." + host << "\red Your head feels a bit roomier.." // Enables the mob to take a lot more damage mob/living/parasite/meme/verb/Analgesic() From e29315a8516585f8cb7729ca594d90c77f1ebd53 Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 21:53:15 +0200 Subject: [PATCH 26/27] Raised the player requirement for meme to its normal value. --- code/game/gamemodes/meme/meme.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index af7a8f06224..19c1d77f6e3 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -3,8 +3,7 @@ /datum/game_mode/meme name = "Memetic Anomaly" config_tag = "meme" - //required_players = 6 - required_players = 2 // for testing + required_players = 6 restricted_jobs = list("AI", "Cyborg") recommended_enemies = 2 // need at least a meme and a host From d087e5791cb6fdc90947ae0eb23f3027f22bcf9a Mon Sep 17 00:00:00 2001 From: cib Date: Sat, 19 May 2012 22:09:39 +0200 Subject: [PATCH 27/27] Fixed grammar mistake. --- code/game/gamemodes/meme/meme.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index 19c1d77f6e3..4db573a6293 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -34,7 +34,7 @@ /datum/game_mode/meme/announce() world << "The current game mode is - Meme!" - world << "An unknown creature has infested the mind of a crew member. Find and destroy it by what means necessary." + world << "An unknown creature has infested the mind of a crew member. Find and destroy it by any means necessary." /datum/game_mode/meme/can_start() if(!..())