Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions changelog.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unrelated changelog additions from this PR (if they are still missing from the changelog at head, feel free to just push them directly, though idk with how old this PR is). I guess even the changelog for MC_POST_CYCLE_RATE_CALCULATE will need to be moved. Or omit the changelog from the PR entirely and push something in afterwards.

Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,22 @@ Additions:
Called after a player drops a card/pill onto the ground from their inventory.
- MC_PRE_PLAYER_GIVE_BIRTH_CAMBION/IMMACULATE (EntityPlayer, CambionFamiliarFlag)
Return false to cancel the familiar being added.
- MC_POST_CYCLE_RATE_CALCULATE (EntityPickup, int CycleNum, int OriginalRate)
Called after the rate at which a collectible is supposed to cycle is calculated (Glitched Crown effect)
Return integer to overwrite cycle rate.
* EntityLaser:
- GetDamageMultiplier()
- SetDamageMultiplier(float Mult)
* ItemPool:
- GetRandomPool(RNG, bool AdvancedSearch, table BlackList)
- PickCollectible(ItemPoolType, bool Decrease, RNG, GetCollectibleFlag)
* RNG:
- GetShiftIdx()
- PhantomNext()
- Previous()
- PhantomPrevious()
* Enums:
- GetCollectibleFlag
- CambionFamiliarFlag
* Added a new option "Extra debug render for FindInRadius". While the DebugFlag.HITSPHERES flag is enabled, debug spheres will be rendered for FindInRadius/QueryRadius calls.
/newline/
Expand All @@ -37,6 +49,8 @@ Modified:
PlayCutscene(CutsceneID, ClearGameState = false)
* Game:
SetDizzyAmount(TargetIntensity, CurrentIntensity) - Providing CurrentIntensity is now optional
* ItemPool:
GetCollectible(ItemPoolType, Decrease, Seed, DefaultItem, Flags) - Now gives access to the hidden flags
* The game no longer prematurely ends the daily run if there was console input, instead blocking it
/newline/
Fixes:
Expand Down
1 change: 1 addition & 0 deletions repentogon/Patches/ASMPatches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ void PerformASMPatches() {
ASMPatchProjectileDeath();
ASMPatchTearDeath();
ASMPatchPrePlayerGiveBirth();
ASMPatchPostCycleRateCalculate();

// Delirium
delirium::AddTransformationCallback();
Expand Down
54 changes: 54 additions & 0 deletions repentogon/Patches/ASMPatches/ASMCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,3 +1084,57 @@ void ASMPatchPrePlayerGiveBirth() {
printf("[REPENTOGON] Patching Entity_Player::TriggerHeartPickedUp at %p for MC_PRE_PLAYER_GIVE_BIRTH_IMMACULATE\n", immaculateAddr);
PreBirthPatch(immaculateAddr, false); // Immaculate
}

// MC_POST_CYCLE_RATE_CALCULATE(1211)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for ref, does this run one every update, or only each time the item "cycles"? Does the timer need to land exactly on the cycle rate, or does the internal code do a >(=) check (mostly just considering the possibility of changing the rate causing it to get stuck permanently. I have not looked at the vanilla code)

Also, does this ONLY run when the pickup is actually a cycling collectible?

uint32_t __stdcall RunPostCycleRateCalculate(Entity_Pickup* collectible, uint32_t originalCycleRate) {
uint32_t cycleRate = originalCycleRate;

const int callbackid = 1211;
if (!CallbackState.test(callbackid - 1000)) {
return originalCycleRate;
}

lua_State* L = g_LuaEngine->_state;
lua::LuaStackProtector protector(L);
lua::LuaCaller caller(L);

lua_rawgeti(L, LUA_REGISTRYINDEX, g_LuaEngine->runCallbackRegistry->key);

lua::LuaResults failure = lua::LuaCaller(L).push(callbackid)
.push(collectible->_cycleCollectibleCount)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fix indentation

.push(collectible, lua::Metatables::ENTITY_PICKUP)
.push(collectible->_cycleCollectibleCount)
.push(originalCycleRate)
.call(1);

if (failure || !lua_isinteger(L, -1)) {
return originalCycleRate;
}

cycleRate = (uint32_t)lua_tointeger(L, -1);
if (cycleRate == 0) { // Since the game uses this number as a divisor a value of 0 would cause a Crash
cycleRate = 1;
}
return cycleRate;
}

void ASMPatchPostCycleRateCalculate() {
SigScan scanner("837f??0075??c787????????00000000");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to new signature standard (ASM.zhl)

scanner.Scan();
void* cycleSig = scanner.GetAddress();

printf("[REPENTOGON] Patching Entity_Pickup::Update at %p for MC_POST_COLLECTIBLE_CYCLE_RATE_CALCULATE\n", cycleSig);

ASMPatch::SavedRegisters reg(ASMPatch::SavedRegisters::GP_REGISTERS_STACKLESS & ~ASMPatch::SavedRegisters::ECX, true);
ASMPatch patch;
patch.AddBytes(ByteBuffer().AddAny((char*)cycleSig, 0x4)) // check if subtype is 0
.AddConditionalRelativeJump(ASMPatcher::CondJumps::JE, (char*)cycleSig + 0x6) // return if subtype is 0
.PreserveRegisters(reg)
.Push(ASMPatch::Registers::ECX) // cycleRate
.Push(ASMPatch::Registers::EDI) // Entity_Pickup*
.AddInternalCall(RunPostCycleRateCalculate) // call RunPostCycleRateCalculate
.CopyRegister(ASMPatch::Registers::ECX, ASMPatch::Registers::EAX) // cycleRate = result
.RestoreRegisters(reg)
.AddRelativeJump((char*)cycleSig + 0x15);
sASMPatcher.PatchAt(cycleSig, &patch);
}
1 change: 1 addition & 0 deletions repentogon/Patches/ASMPatches/ASMCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ void ASMPatchPickupUpdatePickupGhosts();
void ASMPatchProjectileDeath();
void ASMPatchTearDeath();
void ASMPatchPrePlayerGiveBirth();
void ASMPatchPostCycleRateCalculate();
1 change: 1 addition & 0 deletions repentogon/resources/scripts/enums_ex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ ModCallbacks.MC_PLAYER_INIT_PRE_LEVEL_INIT_STATS = 1127
ModCallbacks.MC_PRE_NEW_ROOM = 1200
ModCallbacks.MC_PRE_MEGA_SATAN_ENDING = 1201
ModCallbacks.MC_POST_MODS_LOADED = 1210
ModCallbacks.MC_POST_CYCLE_RATE_CALCULATE = 1211
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No action needed, just noting that this ID is still available

ModCallbacks.MC_POST_ITEM_OVERLAY_SHOW = 1134
ModCallbacks.MC_PRE_RENDER = 1135
ModCallbacks.MC_PRE_OPENGL_RENDER = 1136
Expand Down