diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 8a9f995d26f..eb2d7b924a7 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -20,6 +20,12 @@ datum/mind
var/rev_cooldown = 0
proc/transfer_to(mob/new_character)
+ // multikey information is stored in the mob, not the mind, so
+ // we need to clean this stuff up to avoid multikey alerts
+ current.lastKnownIP = null
+ current.computer_id = null
+
+
if(current)
current.mind = null
@@ -28,6 +34,9 @@ datum/mind
new_character.key = key
+ // mob/Login() will handle setting the new mob's lastKnownIP and
+ // computer_id for us
+
proc/store_memory(new_text)
memory += "[new_text]
"
diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm
index c362caf4d43..a98bc524441 100644
--- a/code/game/gamemodes/meme/meme.dm
+++ b/code/game/gamemodes/meme/meme.dm
@@ -11,7 +11,9 @@
var
- var/datum/mind/first_host = null
+ var/list/datum/mind/first_hosts = list()
+ var/list/assigned_hosts = list()
+
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
@@ -41,23 +43,34 @@
if(!..())
return 0
+ // 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() / 10 * 2, 2)
+
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)
+ // for each 2 possible memes, add one meme and one host
+ while(possible_memes.len >= 2)
+ var/datum/mind/meme = pick(possible_memes)
+ possible_memes.Remove(meme)
- first_host = pick(possible_memes)
+ var/datum/mind/first_host = pick(possible_memes)
+ possible_memes.Remove(first_host)
- modePlayer += meme
- modePlayer += first_host
- memes += meme
+ modePlayer += meme
+ modePlayer += first_host
+ memes += meme
+ first_hosts += first_host
- meme.assigned_role = "MODE" //So they aren't chosen for other jobs.
- meme.special_role = "Meme"
+ // so that we can later know which host belongs to which meme
+ assigned_hosts[meme.key] = first_host
+
+ meme.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ meme.special_role = "Meme"
return 1
@@ -72,6 +85,9 @@
var/mob/original = meme.current
meme.transfer_to(M)
M.clearHUD()
+
+ // get the host for this meme
+ var/datum/mind/first_host = assigned_hosts[meme.key]
M.enter_host(first_host.current)
forge_meme_objectives(meme, first_host)
@@ -79,7 +95,7 @@
break
- // TODO: make it possible to have multiple memes with multiple hosts
+ log_admin("Created [memes.len] memes.")
spawn (rand(waittime_l, waittime_h))
send_intercept()
@@ -135,7 +151,6 @@
var/attuned = 0
if((meme.current) && istype(meme.current,/mob/living/parasite/meme))
world << "The meme was [meme.current.key]."
- world << "The first host was [src:first_host.current.key]."
world << "The last host was [meme.current:host.key]."
world << "Hosts attuned: [attuned]"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 7d9b6d65f85..f38a9d2790b 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -134,6 +134,32 @@ var/global/BSACooldown = 0
M.change_mob_type( /mob/living/simple_animal/constructwraith , 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.")
+
+ ticker.mode.memes += newmeme
+
+ if(delmob)
+ del(M)
+
+
+
if(href_list["view_player_info"])
show_player_info(href_list["view_player_info"])
@@ -2434,7 +2460,8 @@ var/global/BSACooldown = 0
body += "\[ Construct: Armoured , "
body += "Builder , "
body += "Wraith \] "
- body += "Shade"
+ body += "Shade "
+ body += "Meme"
body += "
"
if (M.client)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 750174757f1..795f2cf8ab4 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -892,7 +892,7 @@
switch(alert("You sure you wish to edit this mob's appearance?",,"Yes","No"))
if("No")
return
- if(istype(M,/mob/living/carbon/human/tajaran) || istype(M,/mob/living/carbon/human/birdman))
+ if(istype(M,/mob/living/carbon/human/tajaran))
usr << "\red Humanoid aliens do not have an editable appearance... yet!"
else
var/new_facial = input("Please select facial hair color.", "Character Generation") as color
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 4fc203c2f4e..2c87cf9410a 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -252,6 +252,30 @@
dat += "
| Changeling not found! |
"
dat += ""
+ if(ticker.mode.memes.len > 0)
+ dat += "
| Memes | | |
"
+ for(var/datum/mind/meme in ticker.mode.memes)
+ // BUG: For some reason, the memes themselves aren't showing up, even though the list isn't empty
+ // and the "Meme" header is displayed
+ var/mob/living/parasite/meme/M = meme.current
+ if(M)
+ dat += "| [M.key][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""] | "
+ dat += "PM | "
+ dat += "Show Objective |
"
+
+ // need this check because the meme may be possessing someone right now
+ if(istype(M))
+ dat += "\tAttuned: "
+ for(var/mob/attuned in M.indoctrinated)
+ if(attuned.key)
+ dat += "[attuned.real_name]([attuned.key]) "
+ else
+ dat += "[attuned.real_name] "
+ else
+ dat += " | | Changeling not found! |
"
+ dat += "
"
+
+
if(ticker.mode.wizards.len > 0)
dat += "
| Wizards | | |
"
for(var/datum/mind/wizard in ticker.mode.wizards)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index ffb3d985a1b..73e78818d2c 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1008,6 +1008,13 @@
stat = 1
if (sleeping > 0)
+ if(stat == 0)
+ // BUG: this doesn't seem to happen ever.. probably when you hit sleep willingly,
+ // it automatically adjusts your stat without calling this proc
+
+ // show them a message so they know what's going on
+ src << "\blue You feel very drowsy.. Your eyelids become heavy..."
+
handle_dreams()
adjustHalLoss(-5)
blinded = 1
diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm
index f0c219252fd..e3d7b53d467 100644
--- a/code/modules/mob/living/parasite/meme.dm
+++ b/code/modules/mob/living/parasite/meme.dm
@@ -90,8 +90,8 @@ mob/living/parasite/meme/Life()
src.death()
return
- if(host.blinded) src.blinded = 1
- else src.blinded = 0
+ if(host.blinded && host.stat != 1) src.blinded = 1
+ else src.blinded = 0
mob/living/parasite/meme/death()
@@ -382,10 +382,16 @@ mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob i
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)
@@ -415,10 +421,16 @@ mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob
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)
@@ -441,6 +453,9 @@ mob/living/parasite/meme/verb/AttunedJump(mob/living/carbon/human/target as mob
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"
@@ -459,6 +474,9 @@ mob/living/parasite/meme/verb/Attune()
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"
@@ -511,8 +529,16 @@ mob/living/parasite/meme/verb/Possession()
host_mind.current.clearHUD()
host.update_clothing()
+ dummy << "\blue You feel very drowsy.. Your eyelids become heavy..."
+
+ log_admin("[meme_mind.key] has taken possession of [host]([host_mind.key])")
+ message_admins("[meme_mind.key] has taken possession of [host]([host_mind.key])")
+
sleep(600)
+ log_admin("[meme_mind.key] has lost possession of [host]([host_mind.key])")
+ message_admins("[meme_mind.key] has lost possession of [host]([host_mind.key])")
+
meme_mind.transfer_to(src)
host_mind.transfer_to(host)
meme_mind.current.clearHUD()
@@ -546,6 +572,17 @@ mob/living/parasite/meme/verb/Show_Points()
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
// --------------------------------------------
mob/living/parasite/check_contents_for(t)
diff --git a/html/changelog.html b/html/changelog.html
index 05e53e0ddfd..0661b1565d5 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -48,7 +48,11 @@ should be listed in the changelog upon commit though. Thanks. -->
-
22 May 2012
+
22 May 2012
+
cib updated:
+
+ - Worked out a few problems with meme. They now can see, even if their mob is sleeping. Their actions are properly tracked in admin logs. Their points recharge slightly faster, and can now be seen in the Status tab.
+
Erthilo updated:
- Money can now be split and stacked properly. Carry some with you! Still not used for anything!
@@ -88,6 +92,7 @@ should be listed in the changelog upon commit though. Thanks. -->
- You can now right-click pick up items and open/close closets items. This means cyborgs can now open/close closets with a bit of fiddling!
- Added confirmation pop-up for character slot deletion.
+>>>>>>> ebc2b0ed1f7d59caf31b582fd31c950bbde35f8f