Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:NebulaSS13/Nebula into poldev
Browse files Browse the repository at this point in the history
  • Loading branch information
MistakeNot4892 committed Jan 26, 2025
2 parents 4b42f1b + a6f2110 commit b0634af
Show file tree
Hide file tree
Showing 1,057 changed files with 11,024 additions and 8,572 deletions.
62 changes: 62 additions & 0 deletions .github/ISSUE_TEMPLATE/issue-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: Issue report
about: Create a report about a bug or other issue
title: ''
labels: ''
assignees: ''

---

<!--
Anything inside tags like these is a comment and will not be displayed in the final issue.
Be careful not to write inside them!
Every field other than 'specific information for locating' is required.
If you do not fill out the 'specific information' field, please delete the header.
/!\ Omitting or not answering a required field will result in your issue being closed. /!\
Repeated violation of this rule, or joke or spam issues, will result in punishment.
PUT YOUR ANSWERS ON THE BLANK LINES BELOW THE HEADERS
(The lines with four #'s)
Don't edit them or delete them - it's part of the formatting
-->

#### Description of issue



#### Difference between expected and actual behavior



#### Steps to reproduce



#### Specific information for locating
<!-- e.g. an object name, paste specific message outputs... -->



#### Length of time in which bug has been known to occur
<!--
Be specific if you approximately know the time it's been occurring
for—this can speed up finding the source. If you're not sure
about it, tell us too!
-->



#### Client version, Server revision & Game ID
<!-- Found with the "Show server revision" verb in the OOC tab in game. -->



#### Issue bingo
<!-- Check these by writing an x inside the [ ] (like this: [x])-->
<!-- Don't forget to remove the space between the brackets, or it won't work! -->
- [ ] Issue could be reproduced at least once
- [ ] Issue could be reproduced by different players
- [ ] Issue could be reproduced in multiple rounds
- [ ] Issue happened in a recent (less than 7 days ago) round
- [ ] [Couldn't find an existing issue about this](https://github.com/NebulaSS13/Nebula/issues)
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ This is a quick and dirty set of agreed-upon standards for contributions to the
- If there's a personal dislike of the PR, post about it for discussion. Maybe have an 'on hold for discussion' label. Try to reach a consensus/compromise. Failing a compromise, a majority maintainer vote will decide.
- First person to review approves the PR, second person to review can merge it. If 24 hours pass with no objections, first person can merge the PR themselves.
- PRs can have a 24 hour grace period applied by maintainers if it seems important for discussion and responses to be involved. Don't merge for the grace period if applied (reviews are fine).

### Footguns
A footgun is a pattern, function, assumption etc. that stands a strong chance to shoot you in the foot. They are documented here for ease of reference by new contributors.

#### List footguns
- Adding lists to lists will actually perform a merge, rather than inserting the list as a new record. If you want to insert a list into a list, you need to either:
- double-wrap it, ex. `my_list += list(list("some_new_data" = 25))`
- set the index directly, ex. `my_list[my_list.len] = list("some_new_data" = 25)`
- Using variables and macros as associative list keys have some notable behavior.
- If declaring an associative list using a macro as a key, in a case where the macro does not exist (due to misspelling, etc.), that macro name will be treated as a string value for the associative list. You can guard against this by wrapping the macro in parens, ex. `list( (MY_MACRO_NAME) = "some_value" )`, which will fail to compile instead in cases where the macro doesn't exist.
- If a variable is used as the associative key, it *must* be wrapped in parens, or it will be used as a string key.
12 changes: 12 additions & 0 deletions code/___compile_options.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// If REFTRACK_IN_CI is defined, the reftracker will run in CI.
#define REFTRACK_IN_CI
#if defined(REFTRACK_IN_CI) && defined(UNIT_TEST) && !defined(SPACEMAN_DMM)
#define REFTRACKING_ENABLED
#define GC_FAILURE_HARD_LOOKUP
#define FIND_REF_NO_CHECK_TICK
#endif

// parity with previous behavior where TESTING enabled reftracking
#ifdef TESTING
#define REFTRACKING_ENABLED
#endif
32 changes: 14 additions & 18 deletions code/__defines/ZAS.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,25 @@
}

#ifdef MULTIZAS

var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTHUP, EASTUP, WESTUP, SOUTHUP, NORTHDOWN, EASTDOWN, WESTDOWN, SOUTHDOWN)
var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN)
#define ZAS_CSRFZ_CHECK global.cornerdirsz
#define ZAS_GZN_CHECK global.cardinalz

#define ATMOS_CANPASS_TURF(ret, A, B) \
if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \
ret = BLOCKED; \
} \
else if (B.z != A.z) { \
if (B.z < A.z) { \
ret = (A.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \
} \
else { \
ret = (B.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \
} \
else if (B.z < A.z) { \
ret = (A.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \
} \
else if (A.blocks_air & ZONE_BLOCKED || B.blocks_air & ZONE_BLOCKED) { \
ret = (A.z == B.z) ? ZONE_BLOCKED : AIR_BLOCKED; \
else if(B.z > A.z) { \
ret = (B.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \
} \
else if (A.contents.len) { \
else if ((A.blocks_air & ZONE_BLOCKED) || (B.blocks_air & ZONE_BLOCKED)) { \
ret = ZONE_BLOCKED; \
} \
else if (length(A.contents)) { \
ret = 0;\
for (var/thing in A) { \
var/atom/movable/AM = thing; \
for (var/atom/movable/AM as anything in A) { \
ATMOS_CANPASS_MOVABLE(ret, AM, B); \
if (ret == BLOCKED) { \
break;\
Expand All @@ -88,8 +84,8 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN)
}
#else

var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST)
#define ZAS_CSRFZ_CHECK global.cornerdirs
#define ZAS_GZN_CHECK global.cardinal

#define ATMOS_CANPASS_TURF(ret, A, B) \
if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \
Expand All @@ -98,7 +94,7 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST)
else if (A.blocks_air & ZONE_BLOCKED || B.blocks_air & ZONE_BLOCKED) { \
ret = ZONE_BLOCKED; \
} \
else if (A.contents.len) { \
else if (length(A.contents)) { \
ret = 0;\
for (var/thing in A) { \
var/atom/movable/AM = thing; \
Expand Down
3 changes: 0 additions & 3 deletions code/__defines/_compile_options.dm

This file was deleted.

2 changes: 1 addition & 1 deletion code/__defines/_planes+layers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ What is the naming convention for planes or layers?
#define ABOVE_LIGHTING_PLANE 4 // laser beams, etc. that shouldn't be affected by darkness
#define ABOVE_LIGHTING_LAYER 1
#define BEAM_PROJECTILE_LAYER 2
#define SUPERMATTER_WALL_LAYER 3
#define SUBSPACE_WALL_LAYER 3
#define OBFUSCATION_LAYER 4

#define FULLSCREEN_PLANE 5 // for fullscreen overlays that do not cover the hud.
Expand Down
2 changes: 1 addition & 1 deletion code/__defines/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ The latter will result in a linter warning and will not work correctly.
#define ITEM_FLAG_NOCUFFS BITFLAG(11) // Gloves that have this flag prevent cuffs being applied
#define ITEM_FLAG_CAN_HIDE_IN_SHOES BITFLAG(12) // Items that can be hidden in shoes that permit it
#define ITEM_FLAG_PADDED BITFLAG(13) // When set on gloves, will act like pulling punches in unarmed combat.
#define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be be taped onto something using tape
#define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be taped onto something using tape
#define ITEM_FLAG_IS_WEAPON BITFLAG(15) // Item is considered a weapon. Currently only used for force-based worth calculation.

// Flags for pass_flags (/atom/var/pass_flags)
Expand Down
27 changes: 1 addition & 26 deletions code/__defines/gamemode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#define CHOOSE_GAMEMODE_RETRY 2 // The gamemode could not be chosen; we will use the next most popular option voted in, or the default.
#define CHOOSE_GAMEMODE_REVOTE 3 // The gamemode could not be chosen; we need to have a revote.
#define CHOOSE_GAMEMODE_RESTART 4 // The gamemode could not be chosen; we will restart the server.
#define CHOOSE_GAMEMODE_SILENT_REDO 5 // The gamemode could not be chosen; we request to have the the proc rerun on the next tick.
#define CHOOSE_GAMEMODE_SILENT_REDO 5 // The gamemode could not be chosen; we request to have the proc rerun on the next tick.

//End game state, to manage round end.
#define END_GAME_NOT_OVER 1
Expand Down Expand Up @@ -33,31 +33,6 @@
#define DEFAULT_TELECRYSTAL_AMOUNT 130
#define IMPLANT_TELECRYSTAL_AMOUNT(x) (round(x * 0.49)) // If this cost is ever greater than half of DEFAULT_TELECRYSTAL_AMOUNT then it is possible to buy more TC than you spend

// SPELL FLAGS
#define Z2NOCAST BITFLAG(0) //if this is added, the spell can't be cast at centcomm
#define INCLUDEUSER BITFLAG(1) //does the spell include the caster in its target selection?
#define IGNOREDENSE BITFLAG(2) //are dense turfs ignored in selection?

//End split flags
#define CONSTRUCT_CHECK BITFLAG(12) //used by construct spells - checks for nullrods
#define NO_BUTTON BITFLAG(13) //spell won't show up in the HUD with this

//invocation
#define SpI_SHOUT "shout"
#define SpI_WHISPER "whisper"
#define SpI_EMOTE "emote"
#define SpI_NONE "none"

//upgrading
#define Sp_SPEED "speed"
#define Sp_POWER "power"
#define Sp_TOTAL "total"

//casting costs
#define Sp_RECHARGE "recharge"
#define Sp_CHARGES "charges"
#define Sp_HOLDVAR "holdervar"

//Voting-related
#define VOTE_PROCESS_ABORT 1
#define VOTE_PROCESS_COMPLETE 2
Expand Down
15 changes: 15 additions & 0 deletions code/__defines/item_effects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Identifiers for various categories of item effects.
#define IE_CAT_DAMAGE "weff_damage"
#define IE_CAT_STRIKE "weff_strike"
#define IE_CAT_PARRY "weff_parry"
#define IE_CAT_USED "weff_used"
#define IE_CAT_WIELDED "weff_wield"
#define IE_CAT_VISUAL "weff_visual"
#define IE_CAT_LISTENER "weff_listener"
#define IE_CAT_EXAMINE "weff_visible"
#define IE_CAT_RANGED "weff_ranged"
#define IE_CAT_PROCESS "weff_process"

// Identifiers for parameters for item effects.
#define IE_PAR_USES "uses"
#define IE_PAR_MAX_USES "max_uses"
16 changes: 0 additions & 16 deletions code/__defines/machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define STAGE_THREE 5
#define STAGE_FOUR 7
#define STAGE_FIVE 9
#define STAGE_SUPER 11

// NanoUI flags
#define STATUS_INTERACTIVE 2 // GREEN Visability
Expand Down Expand Up @@ -103,21 +102,6 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define ATMOS_DEFAULT_VOLUME_MIXER 500 // L.
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.

// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse!
#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case.
#define SUPERMATTER_INACTIVE 0 // No or minimal energy
#define SUPERMATTER_NORMAL 1 // Normal operation
#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE
#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged
#define SUPERMATTER_DANGER 4 // Integrity < 50%
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.

#define SUPERMATTER_DATA_EER "Relative EER"
#define SUPERMATTER_DATA_TEMPERATURE "Temperature"
#define SUPERMATTER_DATA_PRESSURE "Pressure"
#define SUPERMATTER_DATA_EPR "Chamber EPR"

// Scrubber modes
#define SCRUBBER_SIPHON "siphon"
#define SCRUBBER_SCRUB "scrub"
Expand Down
8 changes: 8 additions & 0 deletions code/__defines/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,11 @@
#define RADIAL_LABELS_NONE 0
#define RADIAL_LABELS_OFFSET 1
#define RADIAL_LABELS_CENTERED 2

#define CRAYON_DRAW_RUNE "rune"
#define CRAYON_DRAW_GRAFFITI "graffiti"
#define CRAYON_DRAW_LETTER "letter"
#define CRAYON_DRAW_ARROW "arrow"

// Default UI style applied to client prefs.
#define DEFAULT_UI_STYLE /decl/ui_style/midnight
24 changes: 17 additions & 7 deletions code/__defines/qdel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#define QDEL_HINT_IWILLGC 2 //functionally the same as the above. qdel should assume the object will gc on its own, and not check it.
#define QDEL_HINT_HARDDEL 3 //qdel should assume this object won't gc, and queue a hard delete using a hard reference.
#define QDEL_HINT_HARDDEL_NOW 4 //qdel should assume this object won't gc, and hard del it post haste.
#define QDEL_HINT_FINDREFERENCE 5 //functionally identical to QDEL_HINT_QUEUE if TESTING is not enabled in _compiler_options.dm.
//if TESTING is enabled, qdel will call this object's find_references() verb.
#define QDEL_HINT_FINDREFERENCE 5 //functionally identical to QDEL_HINT_QUEUE if REFTRACKING_ENABLED is not enabled in _compiler_options.dm.
//if REFTRACKING_ENABLED is enabled, qdel will call this object's find_references() verb.
#define QDEL_HINT_IFFAIL_FINDREFERENCE 6 //Above but only if gc fails.
//defines for the gc_destroyed var

Expand All @@ -15,21 +15,31 @@
#define GC_QUEUE_HARDDELETE 3
#define GC_QUEUE_COUNT 3 //increase this when adding more steps.

#define GC_QUEUED_FOR_HARD_DEL -1
#define GC_CURRENTLY_BEING_QDELETED -2
// Defines for the ssgarbage queue items
#define GC_QUEUE_ITEM_QUEUE_TIME 1 //! Time this item entered the queue
#define GC_QUEUE_ITEM_REF 2 //! Ref to the item
#define GC_QUEUE_ITEM_GCD_DESTROYED 3 //! Item's gc_destroyed var value. Used to detect ref reuse.
#define GC_QUEUE_ITEM_INDEX_COUNT 3 //! Number of item indexes, used for allocating the nested lists. Don't forget to increase this if you add a new queue item index

// Defines for the time an item has to get its reference cleaned before it fails the queue and moves to the next.
#define GC_FILTER_QUEUE (1 SECONDS)
#define GC_CHECK_QUEUE (5 MINUTES)
#define GC_DEL_QUEUE (10 SECONDS)

#define GC_CURRENTLY_BEING_QDELETED -1

#define QDELING(X) (X.gc_destroyed)
#define QDELETED(X) (isnull(X) || QDELING(X))
#define QDESTROYING(X) (isnull(X) || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)

//Qdel helper macros.
#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE)}
#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)}
#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time)}
#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_CLIENT_TIME)}
#define QDEL_NULL(item) if(item) {qdel(item); item = null}
#define QDEL_NULL_SCREEN(item) if(client) { client.screen -= item; }; QDEL_NULL(item)
#define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) }}; if(x) {x.Cut(); x = null } // Second x check to handle items that LAZYREMOVE on qdel.
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE)
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }

Expand Down
3 changes: 2 additions & 1 deletion code/__defines/research.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
#define HOLLOW_OBJECT_MATTER_MULTIPLIER 0.05
#define BASE_OBJECT_MATTER_MULTPLIER 0.25

#define GENERIC_SMELTING_HEAT_POINT 1350 CELSIUS
#define LOW_SMELTING_HEAT_POINT 1150 CELSIUS // Reachable with coal in a kiln on the medieval maps.
#define GENERIC_SMELTING_HEAT_POINT 1350 CELSIUS // Reachable with coal and a bellows in a kiln on medieval maps.
#define HIGH_SMELTING_HEAT_POINT 4000 CELSIUS // must be at least 4074K (3800 C) to melt graphite

#define TECH_MATERIAL "materials"
Expand Down
1 change: 1 addition & 0 deletions code/__defines/species.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define SPECIES_FLAG_NO_BLOCK BITFLAG(6) // Unable to block or defend itself from attackers.
#define SPECIES_FLAG_NEED_DIRECT_ABSORB BITFLAG(7) // This species can only have their DNA taken by direct absorption.
#define SPECIES_FLAG_LOW_GRAV_ADAPTED BITFLAG(8) // This species is used to lower than standard gravity, affecting stamina in high-grav
#define SPECIES_FLAG_ABSORB_ELECTRICITY BITFLAG(9) // This species can absorb electricity; snowflake flag for old slime people.

// Species spawn flags
#define SPECIES_IS_WHITELISTED BITFLAG(0) // Must be whitelisted to play.
Expand Down
5 changes: 2 additions & 3 deletions code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
#define INITIALIZATION_INSSATOMS_LATE 1 //New should not call Initialize; after the first pass is complete (handled differently)
#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 3 //New should call Initialize(FALSE)
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)

#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
Expand Down
2 changes: 1 addition & 1 deletion code/_helpers/files.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//Sends resource files to client cache
/client/proc/getFiles()
for(var/file in args)
direct_output(src, browse_rsc(file))
send_rsc(src, file, null)

/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
var/path = root
Expand Down
2 changes: 1 addition & 1 deletion code/_helpers/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ mob
// Send the icon to src's local cache
send_rsc(src, getFlatIcon(src), iconName)
// Display the icon in their browser
direct_output(src, browse("<body bgcolor='#000000'><p><img src='[iconName]'></p></body>"))
show_browser(src, "<body bgcolor='#000000'><p><img src='[iconName]'></p></body>")
Output_Icon()
set name = "2. Output Icon"
Expand Down
2 changes: 1 addition & 1 deletion code/_helpers/logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : ""
to_world_log("## TESTING: [msg][log_end]")

/proc/game_log(category, text)
direct_output(diary, "\[[time_stamp()]] [game_id] [category]: [text][log_end]")
to_file(diary, "\[[time_stamp()]] [game_id] [category]: [text][log_end]")

/proc/log_admin(text)
global.admin_log.Add(text)
Expand Down
2 changes: 1 addition & 1 deletion code/_helpers/profiling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
lines += "[entry] => [num2text(data[STAT_ENTRY_TIME], 10)]ms ([data[STAT_ENTRY_COUNT]]) (avg:[num2text(data[STAT_ENTRY_TIME]/(data[STAT_ENTRY_COUNT] || 1), 99)])"

if (user)
direct_output(user, browse("<ol><li>[lines.Join("</li><li>")]</li></ol>", "window=[url_encode("stats:[ref(stats)]")]"))
show_browser(user, "<ol><li>[lines.Join("</li><li>")]</li></ol>", "window=[url_encode("stats:[ref(stats)]")]")

. = lines.Join("\n")

Expand Down
2 changes: 1 addition & 1 deletion code/_helpers/sorts/__main.dm
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ reverse a descending sequence without violating stability.
var/r = 0 //becomes 1 if any bits are shifted off
while(n >= MIN_MERGE)
r |= (n & 1)
n >>= 1
n = BITSHIFT_RIGHT(n, 1)
return n + r

//Examines the stack of runs waiting to be merged and merges adjacent runs until the stack invariants are reestablished:
Expand Down
Loading

0 comments on commit b0634af

Please sign in to comment.