mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user