mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
[MIRROR] Improves duplication [MDB IGNORE] (#18704)
* Improves duplication (#72572) ## About The Pull Request - Improves duplication code significantly - Removes 'perfectcopy', 'newloc', 'nerf' and 'holoitem' args. These were made for holodeck items, but holodeck items do not use this proc so it's since been unused. - Adds many things to duplicate forbidden vars, such as external organs (and fixes internal organs), overlays, and signals. The signal part is what broke basic things for duplicated mobs, such as dying, huds, and lying down. - Duplicated mobs now properly carry over the identity of the old mob without losing anything in the process, and now actually work as a mob, with visible HUDs and everything. They also carry implants over now. - Duplicated mobs also now no longer cut all their contents and rebuild the entire mob, they don't carry overlays at all (so we don't have the problems that come along with it, like clothing sprites from clothes that don't exist). - As a minor detail, makes DuplicateObject use snake_case instead, and makes duplicate_forbidden_vars protected. - Removes copy_contents_to because it's unused. It was originally meant for Holodeck, but holodecks now use map templates so it's no longer used in-game.   ## Why It's Good For The Game Closes https://github.com/tgstation/tgstation/issues/42212 Duplicating mobs no longer gives a broken mob, which was a common problem with cloning pods (the admin pods, that you drop down onto people). Updates very old code to modern code standards. This PR was made to help out https://github.com/tgstation/tgstation/pull/71141 too, the author of that PR is aware of this one. ## Changelog 🆑 refactor: Duplicating mobs now should now give properly functioning mobs, as duplications in general have been reworked. Admins can feel free to use the pod feature on people. /🆑 * Improves duplication Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
co-authored by
John Willard
parent
cb486eb0a7
commit
81cafafbf6
@@ -0,0 +1,93 @@
|
||||
///List of all vars that will not be copied over when using duplicate_object()
|
||||
GLOBAL_LIST_INIT(duplicate_forbidden_vars, list(
|
||||
"actions",
|
||||
"active_hud_list",
|
||||
"active_timers",
|
||||
"AIStatus",
|
||||
"appearance",
|
||||
"area",
|
||||
"atmos_adjacent_turfs",
|
||||
"bodyparts",
|
||||
"ckey",
|
||||
"comp_lookup",
|
||||
"computer_id",
|
||||
"contents",
|
||||
"cooldowns",
|
||||
"datum_components",
|
||||
"external_organs",
|
||||
"external_organs_slot",
|
||||
"group",
|
||||
"hand_bodyparts",
|
||||
"held_items",
|
||||
"hud_list",
|
||||
"implants",
|
||||
"important_recursive_contents",
|
||||
"internal_organs",
|
||||
"internal_organs_slot",
|
||||
"key",
|
||||
"lastKnownIP",
|
||||
"loc",
|
||||
"locs",
|
||||
"managed_overlays",
|
||||
"managed_vis_overlays",
|
||||
"overlays",
|
||||
"overlays_standing",
|
||||
"parent",
|
||||
"parent_type",
|
||||
"power_supply",
|
||||
"quirks",
|
||||
"reagents",
|
||||
"signal_procs",
|
||||
"status_traits",
|
||||
"stat",
|
||||
"tag",
|
||||
"tgui_shared_states",
|
||||
"type",
|
||||
"vars",
|
||||
"verbs",
|
||||
"x", "y", "z",
|
||||
))
|
||||
GLOBAL_PROTECT(duplicate_forbidden_vars)
|
||||
|
||||
/**
|
||||
* # duplicate_object
|
||||
*
|
||||
* Makes a copy of an item and transfers most vars over, barring GLOB.duplicate_forbidden_vars
|
||||
* Args:
|
||||
* original - Atom being duplicated
|
||||
* spawning_location - Turf where the duplicated atom will be spawned at.
|
||||
*/
|
||||
/proc/duplicate_object(atom/original, turf/spawning_location)
|
||||
RETURN_TYPE(original.type)
|
||||
if(!original)
|
||||
return
|
||||
|
||||
var/atom/made_copy = new original.type(spawning_location)
|
||||
|
||||
for(var/atom_vars in original.vars - GLOB.duplicate_forbidden_vars)
|
||||
if(islist(original.vars[atom_vars]))
|
||||
var/list/var_list = original.vars[atom_vars]
|
||||
made_copy.vars[atom_vars] = var_list.Copy()
|
||||
continue
|
||||
else if(istype(original.vars[atom_vars], /datum) || ismob(original.vars[atom_vars]))
|
||||
continue // this would reference the original's object, that will break when it is used or deleted.
|
||||
made_copy.vars[atom_vars] = original.vars[atom_vars]
|
||||
|
||||
if(isliving(made_copy))
|
||||
if(iscarbon(made_copy))
|
||||
var/mob/living/carbon/original_carbon = original
|
||||
var/mob/living/carbon/copied_carbon = made_copy
|
||||
//transfer DNA over (also body features), then update skin color.
|
||||
original_carbon.dna.transfer_identity(copied_carbon, transfer_SE = TRUE)
|
||||
copied_carbon.updateappearance(mutcolor_update = TRUE)
|
||||
|
||||
var/mob/living/original_living = original
|
||||
//transfer implants, we do this so the original's implants being removed won't destroy ours.
|
||||
for(var/obj/item/implant/original_implants as anything in original_living.implants)
|
||||
var/obj/item/implant/copied_implant = new original_implants.type
|
||||
copied_implant.implant(made_copy, silent = TRUE, force = TRUE)
|
||||
//transfer quirks, we do this because transfering the original's quirks keeps the 'owner' as the original.
|
||||
for(var/datum/quirk/original_quirks as anything in original_living.quirks)
|
||||
original_living.add_quirk(original_quirks.type)
|
||||
|
||||
return made_copy
|
||||
@@ -1212,7 +1212,7 @@
|
||||
else if(href_list["dupe_marked_datum"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
return DuplicateObject(marked_datum, perfectcopy=1, newloc=get_turf(usr))
|
||||
return duplicate_object(marked_datum, spawning_location = get_turf(usr))
|
||||
|
||||
else if(href_list["object_list"]) //this is the laggiest thing ever
|
||||
if(!check_rights(R_SPAWN))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
if(LAZYACCESS(modifiers, LEFT_CLICK))
|
||||
var/turf/T = get_turf(object)
|
||||
if(stored)
|
||||
DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T)
|
||||
duplicate_object(stored, spawning_location = T)
|
||||
log_admin("Build Mode: [key_name(c)] copied [stored] to [AREACOORD(object)]")
|
||||
else if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
if(ismovable(object)) // No copying turfs for now.
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
var/bayNumber //Quick reference to what bay we're in. Usually set to the loading_id variable for the related area type
|
||||
var/customDropoff = FALSE
|
||||
var/picking_dropoff_turf = FALSE
|
||||
var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicateObject() and send the result
|
||||
var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicate_object() and send the result
|
||||
var/launchRandomItem = FALSE //If true, lauches a single random item instead of everything on a turf.
|
||||
var/launchChoice = LAUNCH_RANDOM //Determines if we launch all at once (0) , in order (1), or at random(2)
|
||||
var/explosionChoice = 0 //Determines if there is no explosion (0), custom explosion (1), or just do a maxcap (2)
|
||||
@@ -721,7 +721,7 @@
|
||||
/datum/centcom_podlauncher/proc/launch(turf/target_turf) //Game time started
|
||||
if (isnull(target_turf))
|
||||
return
|
||||
var/obj/structure/closet/supplypod/centcompod/toLaunch = DuplicateObject(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result
|
||||
var/obj/structure/closet/supplypod/centcompod/toLaunch = duplicate_object(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result
|
||||
toLaunch.update_appearance()//we update_appearance() here so that the door doesnt "flicker on" right after it lands
|
||||
var/shippingLane = GLOB.areas_by_type[/area/centcom/central_command_areas/supplypod/supplypod_temp_holding]
|
||||
toLaunch.forceMove(shippingLane)
|
||||
@@ -734,7 +734,7 @@
|
||||
toLaunch.turfs_in_cargo += atom_to_launch.type
|
||||
else
|
||||
var/atom/movable/movable_to_launch = launch_candidate
|
||||
DuplicateObject(movable_to_launch).forceMove(toLaunch) //Duplicate a single atom/movable from launchList and forceMove it into the supplypod
|
||||
duplicate_object(movable_to_launch).forceMove(toLaunch) //Duplicate a single atom/movable from launchList and forceMove it into the supplypod
|
||||
else
|
||||
for (var/launch_candidate in launchList)
|
||||
if (isnull(launch_candidate))
|
||||
@@ -744,7 +744,7 @@
|
||||
toLaunch.turfs_in_cargo += turf_to_launch.type
|
||||
else
|
||||
var/atom/movable/movable_to_launch = launch_candidate
|
||||
DuplicateObject(movable_to_launch).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
duplicate_object(movable_to_launch).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
else
|
||||
if(launchRandomItem)
|
||||
var/atom/random_item = pick_n_take(launchList)
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
//Vars that will not be copied when using /DuplicateObject
|
||||
GLOBAL_LIST_INIT(duplicate_forbidden_vars,list(
|
||||
"tag", "datum_components", "area", "type", "loc", "locs", "vars", "parent", "parent_type", "verbs", "ckey", "key",
|
||||
"power_supply", "contents", "reagents", "stat", "x", "y", "z", "group", "atmos_adjacent_turfs", "comp_lookup",
|
||||
"important_recursive_contents", "bodyparts", "internal_organs", "hand_bodyparts", "overlays_standing", "hud_list",
|
||||
"actions", "AIStatus", "appearance", "managed_overlays", "managed_vis_overlays", "computer_id", "lastKnownIP", "implants",
|
||||
"tgui_shared_states"
|
||||
))
|
||||
|
||||
/proc/DuplicateObject(atom/original, perfectcopy = TRUE, sameloc, atom/newloc = null, nerf, holoitem)
|
||||
RETURN_TYPE(original.type)
|
||||
if(!original)
|
||||
return
|
||||
var/atom/O
|
||||
|
||||
if(sameloc)
|
||||
O = new original.type(original.loc)
|
||||
else
|
||||
O = new original.type(newloc)
|
||||
|
||||
if(perfectcopy && O && original)
|
||||
for(var/V in original.vars - GLOB.duplicate_forbidden_vars)
|
||||
if(islist(original.vars[V]))
|
||||
var/list/L = original.vars[V]
|
||||
O.vars[V] = L.Copy()
|
||||
else if(istype(original.vars[V], /datum) || ismob(original.vars[V]))
|
||||
continue // this would reference the original's object, that will break when it is used or deleted.
|
||||
else
|
||||
O.vars[V] = original.vars[V]
|
||||
|
||||
if(isobj(O))
|
||||
var/obj/N = O
|
||||
if(holoitem)
|
||||
N.resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // holoitems do not burn
|
||||
|
||||
if(nerf && isitem(O))
|
||||
var/obj/item/I = O
|
||||
I.damtype = STAMINA // thou shalt not
|
||||
|
||||
N.update_appearance()
|
||||
if(ismachinery(O))
|
||||
var/obj/machinery/M = O
|
||||
M.power_change()
|
||||
if(istype(O, /obj/machinery/button))
|
||||
var/obj/machinery/button/B = O
|
||||
B.setup_device()
|
||||
|
||||
if(holoitem)
|
||||
O.flags_1 |= HOLOGRAM_1
|
||||
for(var/atom/thing in O)
|
||||
thing.flags_1 |= HOLOGRAM_1
|
||||
if(ismachinery(O))
|
||||
var/obj/machinery/M = O
|
||||
for(var/atom/contained_atom in M.component_parts)
|
||||
contained_atom.flags_1 |= HOLOGRAM_1
|
||||
if(M.circuit)
|
||||
M.circuit.flags_1 |= HOLOGRAM_1
|
||||
|
||||
if(ismob(O)) //Overlays are carried over despite disallowing them, if a fix is found remove this.
|
||||
var/mob/M = O
|
||||
M.cut_overlays()
|
||||
M.regenerate_icons()
|
||||
return O
|
||||
|
||||
|
||||
/area/proc/copy_contents_to(area/A , platingRequired = 0, nerf_weapons = 0 )
|
||||
//Takes: Area. Optional: If it should copy to areas that don't have plating
|
||||
//Returns: Nothing.
|
||||
//Notes: Attempts to move the contents of one area to another area.
|
||||
// Movement based on lower left corner. Tiles that do not fit
|
||||
// into the new area will not be moved.
|
||||
|
||||
if(!A || !src)
|
||||
return 0
|
||||
|
||||
var/list/turfs_src = get_area_turfs(src.type)
|
||||
var/list/turfs_trg = get_area_turfs(A.type)
|
||||
|
||||
var/src_min_x = 99999
|
||||
var/src_min_y = 99999
|
||||
var/list/refined_src = new/list()
|
||||
|
||||
for (var/turf/T in turfs_src)
|
||||
src_min_x = min(src_min_x,T.x)
|
||||
src_min_y = min(src_min_y,T.y)
|
||||
for (var/turf/T in turfs_src)
|
||||
refined_src[T] = "[T.x - src_min_x].[T.y - src_min_y]"
|
||||
|
||||
var/trg_min_x = 99999
|
||||
var/trg_min_y = 99999
|
||||
var/list/refined_trg = new/list()
|
||||
|
||||
for (var/turf/T in turfs_trg)
|
||||
trg_min_x = min(trg_min_x,T.x)
|
||||
trg_min_y = min(trg_min_y,T.y)
|
||||
for (var/turf/T in turfs_trg)
|
||||
refined_trg["[T.x - trg_min_x].[T.y - trg_min_y]"] = T
|
||||
|
||||
var/list/toupdate = new/list()
|
||||
|
||||
var/copiedobjs = list()
|
||||
|
||||
for (var/turf/T in refined_src)
|
||||
var/coordstring = refined_src[T]
|
||||
var/turf/B = refined_trg[coordstring]
|
||||
if(!istype(B))
|
||||
continue
|
||||
|
||||
if(platingRequired)
|
||||
if(isspaceturf(B))
|
||||
continue
|
||||
|
||||
var/old_dir1 = T.dir
|
||||
var/old_icon_state1 = T.icon_state
|
||||
var/old_icon1 = T.icon
|
||||
|
||||
B = B.ChangeTurf(T.type)
|
||||
B.setDir(old_dir1)
|
||||
B.icon = old_icon1
|
||||
B.icon_state = old_icon_state1
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/obj/O2 = DuplicateObject(O , perfectcopy=TRUE, newloc = B, nerf=nerf_weapons, holoitem=TRUE)
|
||||
if(!O2)
|
||||
continue
|
||||
copiedobjs += O2.get_all_contents()
|
||||
|
||||
for(var/mob/M in T)
|
||||
if(iscameramob(M))
|
||||
continue // If we need to check for more mobs, I'll add a variable
|
||||
var/mob/SM = DuplicateObject(M , perfectcopy=TRUE, newloc = B, holoitem=TRUE)
|
||||
copiedobjs += SM.get_all_contents()
|
||||
|
||||
for(var/V in T.vars - GLOB.duplicate_forbidden_vars)
|
||||
if(V == "air")
|
||||
var/turf/open/O1 = B
|
||||
var/turf/open/O2 = T
|
||||
O1.air.copy_from(O2.return_air())
|
||||
continue
|
||||
B.vars[V] = T.vars[V]
|
||||
toupdate += B
|
||||
|
||||
if(toupdate.len)
|
||||
for(var/turf/T1 in toupdate)
|
||||
CALCULATE_ADJACENT_TURFS(T1, KILL_EXCITED)
|
||||
|
||||
return copiedobjs
|
||||
+1
-1
@@ -406,6 +406,7 @@
|
||||
#include "code\__HELPERS\dates.dm"
|
||||
#include "code\__HELPERS\datums.dm"
|
||||
#include "code\__HELPERS\dna.dm"
|
||||
#include "code\__HELPERS\duplicating.dm"
|
||||
#include "code\__HELPERS\files.dm"
|
||||
#include "code\__HELPERS\filters.dm"
|
||||
#include "code\__HELPERS\forensics.dm"
|
||||
@@ -3343,7 +3344,6 @@
|
||||
#include "code\modules\holiday\foreign_calendar.dm"
|
||||
#include "code\modules\holiday\holidays.dm"
|
||||
#include "code\modules\holiday\nth_week.dm"
|
||||
#include "code\modules\holodeck\area_copy.dm"
|
||||
#include "code\modules\holodeck\computer.dm"
|
||||
#include "code\modules\holodeck\holo_effect.dm"
|
||||
#include "code\modules\holodeck\holodeck_map_templates.dm"
|
||||
|
||||
Reference in New Issue
Block a user