diff --git a/baystation12.dme b/baystation12.dme
index 27974d2f8c0..d7e295e609e 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1260,6 +1260,8 @@
#include "code\modules\mob\living\carbon\metroid\say.dm"
#include "code\modules\mob\living\carbon\metroid\subtypes.dm"
#include "code\modules\mob\living\carbon\metroid\update_icons.dm"
+#include "code\modules\mob\living\parasite\meme.dm"
+#include "code\modules\mob\living\parasite\meme_captive.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\laws.dm"
#include "code\modules\mob\living\silicon\login.dm"
diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm
index ac78fe70bea..962d6a84f68 100644
--- a/code/game/gamemodes/meme/meme.dm
+++ b/code/game/gamemodes/meme/meme.dm
@@ -6,14 +6,14 @@
name = "Memetic Anomaly"
config_tag = "meme"
required_players = 3
- restricted_jobs = list("AI", "Cyborg")
- recommended_enemies = 2 // need at least a meme and a host
+ //restricted_jobs = list("AI", "Cyborg")
+ //recommended_enemies = 2 // need at least a meme and a host
votable = 0 // temporarily disable this mode for voting
end_on_antag_death = 1
var/var/list/datum/mind/first_hosts = list()
var/var/list/assigned_hosts = list()
-
+/* no objectives
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target
@@ -30,9 +30,9 @@
var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative
var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly
var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly
-
- var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
- var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
+*/
+ //var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
+ //var/const/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!"
@@ -44,7 +44,7 @@
// for every 10 players, get 1 meme, and for each meme, get a host
// also make sure that there's at least one meme and one host
- recommended_enemies = max(src.num_players() / 20 * 2, 2)
+ //recommended_enemies = max(src.num_players() / 20 * 2, 2)
var/list/datum/mind/possible_memes = get_players_for_role(BE_MEME)
@@ -90,7 +90,7 @@
first_host = pick(first_hosts)
first_hosts.Remove(first_host)
M.enter_host(first_host.current)
- forge_meme_objectives(meme, first_host)
+ //forge_meme_objectives(meme, first_host)
qdel(original)
@@ -101,7 +101,7 @@
..()
return
-
+/* no objectives
/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme, var/datum/mind/first_host)
if (config.objectives_disabled)
return
@@ -122,7 +122,7 @@
greet_meme(meme)
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!"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 099256ac43a..ee9d318c3a2 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -173,6 +173,7 @@ proc/admin_notice(var/message, var/rights)
Builder ,
Wraith \]
Shade
+ Meme
"}
body += {"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index cf5d002029f..12df8fd630e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -307,7 +307,26 @@
if("constructbuilder") M.change_mob_type( /mob/living/simple_animal/construct/builder , null, null, delmob )
if("constructwraith") M.change_mob_type( /mob/living/simple_animal/construct/wraith , null, null, delmob )
if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob )
+ if("meme")
+ var/mob/living/parasite/meme/newmeme = new
+ M.mind.transfer_to(newmeme)
+ newmeme.clearHUD()
+ var/found = 0
+ for(var/mob/living/carbon/human/H in world) if(H.client && !H.parasites.len)
+ found = 1
+ newmeme.enter_host(H)
+
+ message_admins("[H] has become [newmeme.key]'s host")
+
+ break
+
+ // if there was no host, abort
+ if(!found)
+ newmeme.mind.transfer_to(M)
+ message_admins("Failed to find host for meme [M.key]. Aborting.")
+
+ qdel(M)
/////////////////////////////////////new ban stuff
else if(href_list["unbanf"])
diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm
new file mode 100644
index 00000000000..f37ed04a7bf
--- /dev/null
+++ b/code/modules/mob/living/parasite/meme.dm
@@ -0,0 +1,702 @@
+// === MEMETIC ANOMALY ===
+// =======================
+//Taken from ancient baystation code- LL
+
+/**
+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.
+**/
+
+// The maximum amount of points a meme can gather.
+var/global/const/MAXIMUM_MEME_POINTS = 750
+var/global/const/MINIMUM_MEME_POINTS = 0
+var/mob/living/parasite/host_brain
+var/controlling
+
+
+// === 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
+ src.loc = host
+ host.parasites.Add(src)
+
+ if(client) client.eye = host
+
+ return 1
+
+/mob/living/parasite/proc/exit_host()
+ src.host.parasites.Remove(src)
+ src.host = null
+ src.loc = null
+
+ return 1
+
+
+// === MEME ===
+// ============
+
+
+
+// Memes use points for many actions
+/mob/living/parasite/meme/var/meme_points = 100
+/mob/living/parasite/meme/var/dormant = 0
+/mob/living/parasite/meme/var/possessing = 0
+
+// Memes have a list of indoctrinated hosts
+/mob/living/parasite/meme/var/list/indoctrinated = list()
+
+/mob/living/parasite/meme/Life()
+ ..()
+
+ if(client)
+ if(blinded) client.eye = null
+ else client.eye = host
+
+ if(!host) return
+ if(possessing == 1 && meme_points == 0)
+ detatch()
+
+ // recover meme points slowly
+ var/gain = 3
+ if(dormant) gain = 9 // dormant recovers points faster
+ //if(possessing) meme_points = min(meme_points - loss, MAXIMUM_MEME_POINTS)
+
+ meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS)
+ if(possessing == 1) meme_points = min(meme_points - gain, MINIMUM_MEME_POINTS)
+ if(possessing == 0) meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS)
+
+ // 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 && host.stat != 1) src.blinded = 1
+ else src.blinded = 0
+
+ if(possessing == 1 && meme_points == 0)
+ detatch()
+
+
+/mob/living/parasite/meme/death()
+ // make sure the mob is on the actual map before gibbing
+ if(host) src.loc = host.loc
+ src.stat = 2
+ ..()
+ del src
+
+// 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
+
+ return host.say(message)
+
+// 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
+
+ return host.whisper(message)
+
+// 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
+
+ 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)
+
+// 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
+
+ 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
+
+ // 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
+ if(candidates.len == 1)
+ target = candidates[1]
+ else
+ 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|anything in text_candidates
+ if(!selected) return null
+
+ target = map_text_to_mob[selected]
+
+ return target
+
+
+// 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
+ use_points(150)
+ return
+
+ var/list/candidates = indoctrinated.Copy()
+ if(!(src.host in candidates))
+ 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 text
+ //if(!speaker) return
+
+ var/message = input("What would you like to say?", "Message") as text
+ if(!message) return
+
+ // 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)
+
+ usr << "You make [target] hear: [rendered]"
+
+// 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.silent)
+ 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.silent += 60
+
+ sleep(1200)
+ 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"
+ set name = "Paralyze(250)"
+ set desc = "Prevents your host from using emote for a while."
+
+ if(!src.host) return
+ /*if(!host.Weaken())
+ 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.Weaken(60)
+
+ sleep(1200)
+ 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()
+ set category = "Meme"
+ set name = "Agony(200)"
+ set desc = "Causes significant pain in your host."
+
+ 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_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."
+
+ host.emote("scream")
+
+ for(var/i=0, i<10, i++)
+ host.stuttering = 2
+ sleep(50)
+ 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")
+ 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"
+ set name = "Joy(200)"
+ set desc = "Causes significant joy in your host."
+
+ if(!src.host) return
+ if(!use_points(200)) return
+
+ spawn
+ var/mob/host = src.host
+ 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."
+
+ 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(mob/living/carbon/human/target as mob in world)
+ set category = "Meme"
+ set name = "Hallucinate(300)"
+ set desc = "Makes your host hallucinate, has a short delay."
+
+ if(!istype(target, /mob/living/carbon/human) || !target.mind)
+ src << "You can't remotely ruin this ones mind."
+ 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
+ if(!target) return
+ if(!use_points(300)) return
+
+ spawn(rand(300,600))
+ if(target) target.hallucination += 400
+
+ 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"
+ 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.."
+ return
+ if(!(target in view(1, host)+src))
+ src << "The target is not close enough."
+ return
+
+ // Find out whether we can speak
+ if (host.silent || (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
+
+ if(target.parasites.len > 0)
+ src << "Your target already is possessed by something.."
+ return
+
+ src.exit_host()
+ src.enter_host(target)
+
+ usr << "You successfully jumped to [target]."
+ log_admin("[src.key] has jumped to [target]")
+ message_admins("[src.key] has 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"
+ 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)
+ 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.disabilities & 64))
+ src << "Your host can't speak.."
+ 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
+
+ // Find out whether the target can hear
+ if(target.disabilities & 32 || target.ear_deaf)
+ src << "Your target doesn't seem to hear you.."
+ return
+
+ if(target.parasites.len > 0)
+ src << "Your target already is possessed by something.."
+ return
+
+ src.exit_host()
+ src.enter_host(target)
+
+ usr << "You successfully jumped to [target]."
+ log_admin("[src.key] has jumped to [target]")
+ message_admins("[src.key] has 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]."
+
+ log_admin("[src.key] has jumped to [target]")
+ message_admins("[src.key] has 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."
+ return
+
+ if(!host) return
+ if(!use_points(400)) return
+
+ src.indoctrinated.Add(host)
+
+ usr << "You successfully indoctrinated [host]."
+ host << "\red Your head feels a bit roomier.."
+
+ log_admin("[src.key] has attuned [host]")
+ message_admins("[src.key] has attuned [host]")
+
+// 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 allows the host to move normally, even under life-threatening pain."
+
+ 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]."
+ host << "\red You feel your body strengthen and your pain subside.."
+ host.analgesic = 60
+ while(host.analgesic > 0)
+ sleep(60)
+ host << "\red The dizziness wears off, and you can feel pain again.."
+
+
+/mob/proc/clearHUD()
+ //update_clothing()
+ if(client) client.screen.Cut()
+
+// Take control of the mob
+/mob/living/parasite/meme/verb/Possession()
+ set category = "Meme"
+ set name = "Possession(500)"
+ set desc = "Take direct control of the host for a while."
+
+ if(!use_points(500)) return
+ if(!host)
+ src << "You have discovered a severe bug - NO HOST. CONTACT DEVELOPER."
+ return
+
+ if(src.stat)
+ src << "You cannot do that in your current state."
+ return
+
+
+ src << "You begin assuming direct control..."
+
+ spawn()
+
+ if(!host || !src || controlling)
+ return
+ else
+
+ src << "\red You shroud your hosts brain, assuming control"
+ host << "\red You can feel thoughts that arent your own begin to dictate your body's actions."
+
+ // host -> brain
+ var/h2b_id = host.computer_id
+ var/h2b_ip= host.lastKnownIP
+ host.computer_id = null
+ host.lastKnownIP = null
+
+ qdel(host_brain)
+ host_brain = new(src)
+
+ host_brain.ckey = host.ckey
+
+ host_brain.name = host.name
+
+ if(!host_brain.computer_id)
+ host_brain.computer_id = h2b_id
+
+ if(!host_brain.lastKnownIP)
+ host_brain.lastKnownIP = h2b_ip
+
+ // self -> host
+ var/s2h_id = src.computer_id
+ var/s2h_ip= src.lastKnownIP
+ src.computer_id = null
+ src.lastKnownIP = null
+
+ host.ckey = src.ckey
+
+ if(!host.computer_id)
+ host.computer_id = s2h_id
+
+ if(!host.lastKnownIP)
+ host.lastKnownIP = s2h_ip
+
+ controlling = 1
+ possessing = 1
+
+ host.verbs += /mob/living/parasite/meme/proc/release_control
+
+ return
+
+/mob/living/parasite/meme/proc/release_control()
+ set category = "Meme"
+ set name = "Release Control"
+ set desc = "Release control of your host's body."
+
+ //var/mob/living/parasite/meme/ME = has_brain_worms() god fucking dammit
+/*
+ if(ME && host_brain)
+ src << "\red You retract, releasing control of [host_brain]"
+*/
+ detatch()
+
+ verbs -= /mob/living/parasite/meme/proc/release_control
+ /*
+ else ALL THE FUCKING CODING SCAFFOLDING
+ src << "\red ERROR NO MEME DETECTED IN THIS MOB, THIS IS A BUG !"
+ */
+/mob/living/parasite/meme/proc/detatch()
+
+ if(!host || !controlling) return
+
+ if(istype(host,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = host
+ var/obj/item/organ/external/head = H.get_organ("head")
+ head.implants -= src
+
+ controlling = 0
+ possessing = 0
+
+ host.verbs -= /mob/living/parasite/meme/proc/release_control
+
+ if(host_brain)
+
+ // these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
+ // computer_id and IP are not updated magically on their own in offline mobs -walter0o
+
+ // host -> self
+ var/h2s_id = host.computer_id
+ var/h2s_ip= host.lastKnownIP
+ host.computer_id = null
+ host.lastKnownIP = null
+
+ src.ckey = host.ckey
+
+ if(!src.computer_id)
+ src.computer_id = h2s_id
+
+ if(!host_brain.lastKnownIP)
+ src.lastKnownIP = h2s_ip
+
+ // brain -> host
+ var/b2h_id = host_brain.computer_id
+ var/b2h_ip= host_brain.lastKnownIP
+ host_brain.computer_id = null
+ host_brain.lastKnownIP = null
+
+ host.ckey = host_brain.ckey
+
+ if(!host.computer_id)
+ host.computer_id = b2h_id
+
+ if(!host.lastKnownIP)
+ host.lastKnownIP = b2h_ip
+
+ qdel(host_brain)
+
+
+// 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
+
+ usr << "You enter dormant mode.. You won't be able to take action until all your points have recharged."
+
+ dormant = 1
+
+ while(meme_points < MAXIMUM_MEME_POINTS)
+ sleep(10)
+
+ dormant = 0
+
+ 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]"
+
+// Stat panel to show meme points, copypasted from alien
+/mob/living/parasite/meme/Stat()
+ ..()
+ statpanel("Status")
+ if (client && client.holder)
+ stat(null, "([x], [y], [z])")
+
+ if (client && client.statpanel == "Status")
+ stat(null, "Meme Points: [src.meme_points]")
+/*
+// Game mode helpers, used for theft objectives-NOT USED, NO OBJECTIVES
+// --------------------------------------------
+/mob/living/parasite/check_contents_for(t)
+ if(!host) return 0
+
+ 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)
+ */
diff --git a/code/modules/mob/living/parasite/meme_captive.dm b/code/modules/mob/living/parasite/meme_captive.dm
new file mode 100644
index 00000000000..dd1c95a3601
--- /dev/null
+++ b/code/modules/mob/living/parasite/meme_captive.dm
@@ -0,0 +1,60 @@
+/mob/living/parasite/captive_brain
+ name = "host brain"
+ real_name = "host brain"
+ universal_understand = 1
+
+/mob/living/parasite/captive_brain/say(var/message)
+
+ if (src.client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "\red You cannot speak in IC (muted)."
+ return
+ if (src.client.handle_spam_prevention(message,MUTE_IC))
+ return
+
+ if(istype(src.loc,/mob/living/parasite/meme))
+
+ message = sanitize(message)
+ if (!message)
+ return
+ log_say("[key_name(src)] : [message]")
+ if (stat == 2)
+ return say_dead(message)
+
+ var/mob/living/parasite/meme/ME = src.loc
+ src << "You whisper silently, \"[message]\""
+ ME.host << "The captive mind of [src] whispers, \"[message]\""
+
+ for (var/mob/M in player_list)
+ if (istype(M, /mob/new_player))
+ continue
+ else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
+ M << "The captive mind of [src] whispers, \"[message]\""
+
+/mob/living/parasite/captive_brain/emote(var/message)
+ return
+/* In the event we want to add the ability to resist, its here.
+/mob/living/parasite/captive_brain/process_resist()
+ //Resisting control by an alien mind.
+ if(istype(src.loc,/mob/living/simple_animal/borer))
+ var/mob/living/simple_animal/borer/B = src.loc
+ var/mob/living/captive_brain/H = src
+
+ H << "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)."
+ B.host << "You feel the captive mind of [src] begin to resist your control."
+
+ spawn(rand(200,250)+B.host.brainloss)
+ if(!B || !B.controlling) return
+
+ B.host.adjustBrainLoss(rand(5,10))
+ H << "With an immense exertion of will, you regain control of your body!"
+ B.host << "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you."
+ B.detatch()
+ verbs -= /mob/living/carbon/proc/release_control
+ verbs -= /mob/living/carbon/proc/punish_host
+ verbs -= /mob/living/carbon/proc/spawn_larvae
+
+ return
+
+ ..()
+*/
\ No newline at end of file
diff --git a/html/changelogs/[Lord Lag] - [Memetic].yml b/html/changelogs/[Lord Lag] - [Memetic].yml
new file mode 100644
index 00000000000..755b5fc4942
--- /dev/null
+++ b/html/changelogs/[Lord Lag] - [Memetic].yml
@@ -0,0 +1,6 @@
+author: Lord Lag
+
+delete-after: True
+
+changes:
+ - experiment: "Memetic anomaly code has been introduced"