Removes some seriously confused code regarding transferral of minds to ghosts upon death/gibbing.

The main problem is: if a mind is transferred to a ghost, objectives that have that mind as a target will treat the ghost as the target mob. Which is clearly a problem. This should fix exploits where people could force people to win/lose objectives via ghosting, gibbing, etc.

It should also eliminate any other weird bugs like the one Nodrak fixed a while ago where pais would keep their mind....meaning they were like, a cultist pai or something and could rat antags out to its owner using the HUD.

Removed some conditions from objectives (like those pertaining to the thunderdome) as they were bait for meta. >ghost >teleport to thunderdome >antag fails the objective she completed

Resolves issue 662

Fixes a few instances of original_name becomming null (there's still loads)


git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4214 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
elly1989@rocketmail.com
2012-07-29 09:21:57 +00:00
parent 1120fb50c9
commit 4fcbd6e169
14 changed files with 85 additions and 102 deletions

View File

@@ -1042,6 +1042,7 @@
brainmob = new(src) brainmob = new(src)
brainmob.name = H.real_name brainmob.name = H.real_name
brainmob.real_name = H.real_name brainmob.real_name = H.real_name
brainmob.original_name = H.original_name
brainmob.dna = H.dna brainmob.dna = H.dna
brainmob.timeofhostdeath = H.timeofdeath brainmob.timeofhostdeath = H.timeofdeath
if(H.mind) if(H.mind)

View File

@@ -51,12 +51,10 @@ datum/objective/assassinate
check_completion() check_completion()
if(target && target.current) if(target && target.current)
if(target.current.stat == 2 || istype(target.current.loc.loc, /area/tdome) || issilicon(target.current) || isbrain(target.current)) //Assuming this works, people in the thunderdome and borgs now count as dead for traitor objectives. --NeoFite if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current)) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
return 1 return 1
else return 0
return 0 return 1
else
return 1
@@ -78,19 +76,15 @@ datum/objective/mutiny
explanation_text = "Free Objective" explanation_text = "Free Objective"
return target return target
check_completion() check_completion()
if(target && target.current) if(target && target.current)
var/turf/T = get_turf(target.current) if(target.current.stat == DEAD)
if(target.current.stat == 2)
return 1 return 1
else if((T) && (T.z != 1))//If they leave the station they count as dead for this var/turf/T = get_turf(target.current)
if(T && (T.z != 1)) //If they leave the station they count as dead for this
return 2 return 2
else return 0
return 0 return 1
else
return 1
datum/objective/debrain//I want braaaainssss datum/objective/debrain//I want braaaainssss
@@ -111,21 +105,21 @@ datum/objective/debrain//I want braaaainssss
explanation_text = "Free Objective" explanation_text = "Free Objective"
return target return target
check_completion() check_completion()
if(!target)//If it's a free objective. if(!target)//If it's a free objective.
return 1 return 1
if(!owner.current||owner.current.stat==2)//If you're otherwise dead. if( !owner.current || owner.current.stat==DEAD )//If you're otherwise dead.
return 0 return 0
var/list/all_items = owner.current.get_contents() if( !target.current || !isbrain(target.current) )
for(var/obj/item/device/mmi/mmi in all_items) return 0
if(mmi.brainmob&&mmi.brainmob.mind==target) return 1 var/atom/A = target.current
for(var/obj/item/brain/brain in all_items) while(A.loc) //check to see if the brainmob is on our person
if(brain.brainmob&&brain.brainmob.mind==target) return 1 A = A.loc
if(A == owner.current)
return 1
return 0 return 0
datum/objective/protect//The opposite of killing a dude. datum/objective/protect//The opposite of killing a dude.
find_target() find_target()
..() ..()
@@ -144,43 +138,37 @@ datum/objective/protect//The opposite of killing a dude.
explanation_text = "Free Objective" explanation_text = "Free Objective"
return target return target
check_completion() check_completion()
if(!target)//If it's a free objective. if(!target) //If it's a free objective.
return 1 return 1
if(target.current) if(target.current)
if(target.current.stat == 2 || istype(target.current.loc.loc, /area/tdome) || issilicon(target.current) || isbrain(target.current)) if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current))
return 0 return 0
else return 1
return 1 return 0
else
return 0
datum/objective/hijack datum/objective/hijack
explanation_text = "Hijack the emergency shuttle by escaping alone." explanation_text = "Hijack the emergency shuttle by escaping alone."
check_completion() check_completion()
if(istype(owner.current, /mob/living/silicon)) if(!owner.current || owner.current.stat)
return 0 return 0
if(emergency_shuttle.location<2) if(emergency_shuttle.location<2)
return 0 return 0
if(!owner.current || owner.current.stat) if(issilicon(owner.current))
return 0 return 0
var/area/shuttle = locate(/area/shuttle/escape/centcom) var/area/shuttle = locate(/area/shuttle/escape/centcom)
var/protected_mobs[] = list(/mob/living/silicon/ai, /mob/living/silicon/pai) var/list/protected_mobs = list(/mob/living/silicon/ai, /mob/living/silicon/pai)
for(var/mob/living/player in player_list) for(var/mob/living/player in player_list)
if(player.type in protected_mobs) continue if(player.type in protected_mobs) continue
if (player.mind && (player.mind != owner)) if (player.mind && (player.mind != owner))
if (!player.stat) //they're not dead or in crit if(player.stat != DEAD) //they're not dead!
if (get_turf(player) in shuttle) if(get_turf(player) in shuttle)
return 0 return 0
return 1 return 1
datum/objective/block datum/objective/block
explanation_text = "Do not allow any humans to escape on the shuttle alive." explanation_text = "Do not allow any humans to escape on the shuttle alive."
@@ -274,14 +262,13 @@ datum/objective/survive
check_completion() check_completion()
if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
return 0 //Brains no longer win survive objectives. --NEO
if(issilicon(owner.current) && owner.current != owner.original) if(issilicon(owner.current) && owner.current != owner.original)
return 0 return 0
if(!owner.current || owner.current.stat == 2 || isbrain(owner.current)) //Brains no longer win survive objectives. --NEO
return 0
return 1 return 1
datum/objective/nuclear datum/objective/nuclear
explanation_text = "Destroy the station with a nuclear device." explanation_text = "Destroy the station with a nuclear device."

View File

@@ -114,10 +114,12 @@
//Start growing a human clone in the pod! //Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(mob/ghost as mob, var/clonename, var/ui, var/se, var/mindref, var/mrace, var/UI, var/datum/changeling/changelingClone) /obj/machinery/clonepod/proc/growclone(mob/ghost as mob, var/clonename, var/ui, var/se, var/mindref, var/mrace, var/UI, var/datum/changeling/changelingClone)
if(((!ghost) || (!ghost.client)) || src.mess || src.attempting) if(!(ghost && ghost.client) || src.mess || src.attempting)
return 0 return 0
var/datum/mind/clonemind = locate(mindref) in ticker.minds
if( !(clonemind && istype(clonemind) && clonemind.current && clonemind.current.stat==DEAD) )
return 0
src.attempting = 1 //One at a time!! src.attempting = 1 //One at a time!!
src.locked = 1 src.locked = 1
@@ -147,25 +149,14 @@
src.occupant << "\blue <b>Clone generation process initiated.</b>" src.occupant << "\blue <b>Clone generation process initiated.</b>"
src.occupant << "\blue This will take a moment, please hold." src.occupant << "\blue This will take a moment, please hold."
if(clonename) if(!clonename) //to prevent null names
src.occupant.real_name = clonename clonename = "clone ([rand(0,999)])"
src.occupant.original_name = clonename //we don't want random ghost names should we die again.
else
src.occupant.real_name = "clone" //No null names!!
occupant.real_name = clonename
occupant.original_name = clonename //we don't want random ghost names should we die again.
var/datum/mind/clonemind = (locate(mindref) in ticker.minds) clonemind.transfer_to(src.occupant)
clonemind.original = src.occupant
if ((clonemind) && (istype(clonemind))) //Move that mind over!!
clonemind.transfer_to(src.occupant)
clonemind.original = src.occupant
else //welp
src.occupant.mind = new /datum/mind( )
src.occupant.mind.key = src.occupant.key
src.occupant.mind.current = src.occupant
src.occupant.mind.original = src.occupant
src.occupant.mind.transfer_to(src.occupant)
ticker.minds += src.occupant.mind
// -- Mode/mind specific stuff goes here // -- Mode/mind specific stuff goes here
@@ -216,7 +207,7 @@
return return
if((src.occupant) && (src.occupant.loc == src)) if((src.occupant) && (src.occupant.loc == src))
if((src.occupant.stat == 2) || (src.occupant.suiciding)) //Autoeject corpses and suiciding dudes. if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes.
src.locked = 0 src.locked = 0
src.go_out() src.go_out()
src.connected_message("Clone Rejected: Deceased.") src.connected_message("Clone Rejected: Deceased.")

View File

@@ -368,7 +368,7 @@
else if (href_list["clone"]) else if (href_list["clone"])
var/datum/data/record/C = locate(href_list["clone"]) var/datum/data/record/C = locate(href_list["clone"])
//Look for that player! They better be dead! //Look for that player! They better be dead!
if(C) if(istype(C))
var/mob/selected = find_dead_player("[C.fields["ckey"]]") var/mob/selected = find_dead_player("[C.fields["ckey"]]")
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.

View File

@@ -418,7 +418,7 @@
//this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO //this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO
if(M.key)//Revised. /N if(M.key)//Revised. /N
M.ghostize(1) M.ghostize()
if(brainmob.mind) if(brainmob.mind)
brainmob.mind.transfer_to(M) brainmob.mind.transfer_to(M)

View File

@@ -448,7 +448,7 @@
holder.state = 2 holder.state = 2
update_admins(rank) update_admins(rank)
if(!istype(mob, /mob/dead/observer)) if(!istype(mob, /mob/dead/observer))
mob.adminghostize(1) mob.adminghostize()
src << "\blue You are now observing" src << "\blue You are now observing"
feedback_add_details("admin_verb","O") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! feedback_add_details("admin_verb","O") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -1,4 +1,4 @@
/mob/dead/observer/New(mob/body, var/safety = 0) /mob/dead/observer/New(mob/body, var/can_reenter_corpse = 1)
invisibility = 10 invisibility = 10
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = 15 see_invisible = 15
@@ -13,15 +13,28 @@
if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position
loc = T loc = T
if(ismob(body)) if(ismob(body))
real_name = body.real_name if(body.original_name)
original_name = body.original_name //Original name is only used in ghost chat! It is not to be edited by anything! original_name = body.original_name
name = body.original_name else
if(!safety) if(body.real_name)
original_name = body.real_name
else
original_name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
if(body.real_name)
real_name = body.real_name
else
real_name = original_name
name = original_name
if(!can_reenter_corpse)
corpse = body corpse = body
if(!name) //To prevent nameless ghosts if(!name) //To prevent nameless ghosts
name = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
real_name = name real_name = name
return original_name = name
return
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) /mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return 1 return 1
@@ -30,21 +43,11 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above. Works together with spawning an observer, noted above.
*/ */
/mob/proc/ghostize(var/transfer_mind = 0) /mob/proc/ghostize(var/can_reenter_corpse = 1)
if(key) if(key)
var/mob/dead/observer/ghost = new(src,transfer_mind) //Transfer safety to observer spawning proc. var/mob/dead/observer/ghost = new(src,can_reenter_corpse) //Transfer safety to observer spawning proc.
ghost.attack_log = attack_log //preserve our attack logs by copying them to our ghost ghost.attack_log = attack_log //preserve our attack logs by copying them to our ghost
if(transfer_mind && mind) //When a body is destroyed attempt to transfer their mind ghost.key = key
mind.transfer_to(ghost)
else //Else just modify their key and connect them.
ghost.key = key
else if(transfer_mind) //Body getting destroyed but the person is not present inside.
for(var/mob/dead/observer/O in dead_mob_list)
if(O.corpse == src && O.key) //If they have the same corpse and are keyed.
if(mind)
O.mind = mind //Transfer their mind if they have one.
break
return return
/* /*
@@ -56,11 +59,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Relinquish your life and enter the land of the dead." set desc = "Relinquish your life and enter the land of the dead."
if(stat == DEAD) if(stat == DEAD)
ghostize(0) ghostize(1)
else else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you may not play again this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you may not play again this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost") return //didn't want to ghost after-all if(response != "Ghost") return //didn't want to ghost after-all
ghostize(1) //safety is on so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
return return
/mob/proc/adminghostize() /mob/proc/adminghostize()
@@ -78,14 +81,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
loc = get_turf(src) //Get out of closets and such as a ghost loc = get_turf(src) //Get out of closets and such as a ghost
if((direct & NORTH) && y < world.maxy) if((direct & NORTH) && y < world.maxy)
y++ y++
if((direct & SOUTH) && y > 1) else if((direct & SOUTH) && y > 1)
y-- y--
if((direct & EAST) && x < world.maxx) if((direct & EAST) && x < world.maxx)
x++ x++
if((direct & WEST) && x > 1) else if((direct & WEST) && x > 1)
x-- x--
for(var/obj/effect/step_trigger/S in locate(x, y, z)) for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb
S.HasEntered(src) S.HasEntered(src)
/mob/dead/observer/examine() /mob/dead/observer/examine()
@@ -131,6 +134,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
for(var/obj/effect/rune/R in world) for(var/obj/effect/rune/R in world)
if(corpse.loc==R.loc && R.word1 == wordhell && R.word2 == wordtravel && R.word3 == wordself) if(corpse.loc==R.loc && R.word1 == wordhell && R.word2 == wordtravel && R.word3 == wordself)
S=1 S=1
break
if(!S) if(!S)
usr << "\red The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you." usr << "\red The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you."
return return

View File

@@ -13,10 +13,10 @@
..() ..()
Del() Del()
if(key)//If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat!=2)//If not dead. if(stat!=DEAD) //If not dead.
death(1)//Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize(1)//Ghostize checks for key so nothing else is necessary. (1) tells that it the original body will be destroyed. ghostize() //Ghostize checks for key so nothing else is necessary.
..() ..()
say_understands(var/other) say_understands(var/other)

View File

@@ -5,7 +5,7 @@
if(!gibbed) if(!gibbed)
if(istype(src, /mob/living/carbon/metroid/adult)) if(istype(src, /mob/living/carbon/metroid/adult))
ghostize(1) ghostize()
explosion(loc, -1,-1,3,12) explosion(loc, -1,-1,3,12)
if(src) del(src) if(src) del(src)
else else

View File

@@ -14,5 +14,5 @@
//Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak //Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak
if(mind) del(mind) if(mind) del(mind)
living_mob_list -= src living_mob_list -= src
ghostize(0) ghostize()
del(src) del(src)

View File

@@ -41,7 +41,7 @@
for(var/mob/M in viewers(src, null)) for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded ))) if((M.client && !( M.blinded )))
M.show_message("\red [src] collapses in a shattered heap ") M.show_message("\red [src] collapses in a shattered heap ")
ghostize(0) ghostize()
del src del src
return return

View File

@@ -42,7 +42,7 @@
for(var/mob/M in viewers(src, null)) for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded ))) if((M.client && !( M.blinded )))
M.show_message("\red [src] collapses in a shattered heap ") M.show_message("\red [src] collapses in a shattered heap ")
ghostize(0) ghostize()
del src del src
return return
@@ -181,7 +181,7 @@
for(var/mob/M in viewers(src, null)) for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded ))) if((M.client && !( M.blinded )))
M.show_message("\red [src] collapses in a shattered heap ") M.show_message("\red [src] collapses in a shattered heap ")
ghostize(0) ghostize()
del src del src
return return
@@ -315,7 +315,7 @@
for(var/mob/M in viewers(src, null)) for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded ))) if((M.client && !( M.blinded )))
M.show_message("\red [src] collapses in a shattered heap ") M.show_message("\red [src] collapses in a shattered heap ")
ghostize(0) ghostize()
del src del src
return return

View File

@@ -32,7 +32,7 @@
for(var/mob/M in viewers(src, null)) for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded ))) if((M.client && !( M.blinded )))
M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") M.show_message("\red [src] lets out a contented sigh as their form unwinds. ")
ghostize(0) ghostize()
del src del src
return return

View File

@@ -1,5 +1,5 @@
/mob/Del()//This makes sure that mobs with clients/keys are not just deleted from the game. /mob/Del()//This makes sure that mobs with clients/keys are not just deleted from the game.
ghostize(1) ghostize()
remove_from_mob_list(src) remove_from_mob_list(src)
..() ..()