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.name = H.real_name
brainmob.real_name = H.real_name
brainmob.original_name = H.original_name
brainmob.dna = H.dna
brainmob.timeofhostdeath = H.timeofdeath
if(H.mind)

View File

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

View File

@@ -114,10 +114,12 @@
//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)
if(((!ghost) || (!ghost.client)) || src.mess || src.attempting)
if(!(ghost && ghost.client) || src.mess || src.attempting)
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.locked = 1
@@ -147,25 +149,14 @@
src.occupant << "\blue <b>Clone generation process initiated.</b>"
src.occupant << "\blue This will take a moment, please hold."
if(clonename)
src.occupant.real_name = clonename
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!!
if(!clonename) //to prevent null names
clonename = "clone ([rand(0,999)])"
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)
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
clonemind.transfer_to(src.occupant)
clonemind.original = src.occupant
// -- Mode/mind specific stuff goes here
@@ -216,7 +207,7 @@
return
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.go_out()
src.connected_message("Clone Rejected: Deceased.")

View File

@@ -368,7 +368,7 @@
else if (href_list["clone"])
var/datum/data/record/C = locate(href_list["clone"])
//Look for that player! They better be dead!
if(C)
if(istype(C))
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.

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
if(M.key)//Revised. /N
M.ghostize(1)
M.ghostize()
if(brainmob.mind)
brainmob.mind.transfer_to(M)

View File

@@ -448,7 +448,7 @@
holder.state = 2
update_admins(rank)
if(!istype(mob, /mob/dead/observer))
mob.adminghostize(1)
mob.adminghostize()
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!

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
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = 15
@@ -13,15 +13,28 @@
if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position
loc = T
if(ismob(body))
real_name = body.real_name
original_name = body.original_name //Original name is only used in ghost chat! It is not to be edited by anything!
name = body.original_name
if(!safety)
if(body.original_name)
original_name = body.original_name
else
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
if(!name) //To prevent nameless ghosts
name = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names)))
real_name = name
return
if(!name) //To prevent nameless ghosts
name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
real_name = name
original_name = name
return
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
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.
*/
/mob/proc/ghostize(var/transfer_mind = 0)
/mob/proc/ghostize(var/can_reenter_corpse = 1)
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
if(transfer_mind && mind) //When a body is destroyed attempt to transfer their mind
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
ghost.key = key
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."
if(stat == DEAD)
ghostize(0)
ghostize(1)
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")
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
/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
if((direct & NORTH) && y < world.maxy)
y++
if((direct & SOUTH) && y > 1)
else if((direct & SOUTH) && y > 1)
y--
if((direct & EAST) && x < world.maxx)
x++
if((direct & WEST) && x > 1)
else if((direct & WEST) && x > 1)
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)
/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)
if(corpse.loc==R.loc && R.word1 == wordhell && R.word2 == wordtravel && R.word3 == wordself)
S=1
break
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."
return

View File

@@ -13,10 +13,10 @@
..()
Del()
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.
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.
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat!=DEAD) //If not dead.
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize() //Ghostize checks for key so nothing else is necessary.
..()
say_understands(var/other)

View File

@@ -5,7 +5,7 @@
if(!gibbed)
if(istype(src, /mob/living/carbon/metroid/adult))
ghostize(1)
ghostize()
explosion(loc, -1,-1,3,12)
if(src) del(src)
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
if(mind) del(mind)
living_mob_list -= src
ghostize(0)
ghostize()
del(src)

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/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)
..()