-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
219 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
# Wave Trail Drag Fix | ||
|
||
Fixes the wave trail when interacting with D-blocks. | ||
|
||
![without](nytelyte.wave_trail_drag_fix/without.png) | ||
![Example Image: Without the mod](nytelyte.wave_trail_drag_fix/without.png) | ||
|
||
Without the mod | ||
|
||
![with](nytelyte.wave_trail_drag_fix/with.png) | ||
![Example Image: With the mod](nytelyte.wave_trail_drag_fix/with.png) | ||
|
||
With the mod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,11 @@ | ||
{ | ||
"geode": "2.0.0-beta.22", | ||
"gd": { | ||
"android": "2.205", | ||
"win": "2.204" | ||
}, | ||
"version": "v1.1.7", | ||
"id": "nytelyte.wave_trail_drag_fix", | ||
"name": "Wave Trail Drag Fix", | ||
"developer": "NyteLyte", | ||
"description": "Fix the wave trail being buggy on D blocks.", | ||
"repository": "https://github.com/nytelytee/geode-wave-trail-drag-fix", | ||
"resources": { | ||
"sprites": [ | ||
"resources/with.png", | ||
"resources/without.png" | ||
] | ||
} | ||
"geode": "2.0.0-beta.23", | ||
"gd": {"android": "2.205", "win": "2.204"}, | ||
"version": "v1.2.0", | ||
"id": "nytelyte.wave_trail_drag_fix", | ||
"name": "Wave Trail Drag Fix", | ||
"developer": "NyteLyte", | ||
"description": "Fix the wave trail being buggy on D blocks.", | ||
"repository": "https://github.com/nytelytee/geode-wave-trail-drag-fix", | ||
"resources": {"files": ["resources/examples/with.png", "resources/examples/without.png"]} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,207 @@ | ||
#include <Geode/Geode.hpp> | ||
#include <Geode/modify/PlayerObject.hpp> | ||
#include <Geode/modify/PlayLayer.hpp> | ||
#include <Geode/modify/GJBaseGameLayer.hpp> | ||
|
||
using namespace geode::prelude; | ||
|
||
class $modify(PlayerObject) { | ||
class $modify(WTDFPlayerObject, PlayerObject) { | ||
|
||
// why is there so much state to keep track of | ||
// this used to be so simple | ||
bool forceAdd = true; | ||
bool dontAdd = false; | ||
bool forceAddSpiderRing = false; | ||
bool justTeleported = false; | ||
bool teleportedPreviously = false; | ||
bool transitionToCollision = false; | ||
float portalTargetLine; | ||
CCPoint previousPos{-12, -12}; | ||
CCPoint currentPos{-12, -12}; | ||
CCPoint nextPosNoCollision{-12, -12}; | ||
|
||
cocos2d::CCPoint prev_position{-12, -12}; | ||
void resetObject() { | ||
m_waveTrail->reset(); | ||
PlayerObject::resetObject(); | ||
m_fields->forceAdd = true; | ||
} | ||
|
||
void activateStreak() { | ||
PlayerObject::activateStreak(); | ||
m_fields->dontAdd = true; | ||
} | ||
|
||
bool force_add = true; | ||
bool dont_add = false; | ||
|
||
void resetObject() { | ||
m_fields->force_add = true; | ||
PlayerObject::resetObject(); | ||
} | ||
|
||
void postCollision(float p0) { | ||
PlayerObject::postCollision(p0); | ||
void update(float p0) { | ||
// i used to just use m_position as the current position, but apparently that only gets updated once per frame | ||
// this became really apparent once Click Between Frames came out, so i guess i am going back to doing it this way | ||
// i would have had to do this anyway to get nextPosNoCollision, so yeah | ||
m_fields->currentPos = getRealPosition(); | ||
PlayerObject::update(p0); | ||
m_fields->nextPosNoCollision = getRealPosition(); | ||
} | ||
|
||
if (LevelEditorLayer::get()) return; | ||
if (!m_isDart) { | ||
m_fields->prev_position = m_position; | ||
return; | ||
} | ||
|
||
CCPoint previous_position = m_fields->prev_position; | ||
CCPoint current_position = m_position; | ||
CCPoint next_position = getRealPosition(); | ||
|
||
if (m_fields->force_add) { | ||
m_fields->force_add = false; | ||
m_waveTrail->addPoint(current_position); | ||
m_fields->prev_position = current_position; | ||
return; | ||
} | ||
|
||
cocos2d::CCPoint current_vector = next_position - current_position; | ||
cocos2d::CCPoint previous_vector = current_position - previous_position; | ||
float cross_product_magnitude = abs(current_vector.cross(previous_vector)); | ||
void postCollision(float p0) { | ||
PlayerObject::postCollision(p0); | ||
|
||
if (cross_product_magnitude > 0.01 && !m_fields->dont_add) { | ||
m_waveTrail->addPoint(current_position); | ||
// save the previous point that was a hit, for later calculation | ||
// rather than the current point always | ||
// this makes it so that even smooth paths where | ||
// any 3 consecutive points may look like a straight line | ||
// still get marked for new point addition, because | ||
// we are no longer checking for 3 consecutive points | ||
// this accounts for the wave going in very changing smooth curves | ||
// but one issue is that the cumulative error eventually gets large enough | ||
// that a point is placed even when moving in a constant direction | ||
// i don't think that can be recreated unless you use the zoom trigger to | ||
// zoom the game out up to a point where you can't even notice that extra point anymore though | ||
// basically, this trades off accounting for one type of cumulative error | ||
// (slowly moving smooth transitions not being detected as actually changing moving) | ||
// over another (the an unchanged direction being detected as a change in direction over a long period of time) | ||
m_fields->prev_position = current_position; | ||
} | ||
else if (m_fields->dont_add) { | ||
m_fields->dont_add = false; | ||
// also update the position if we overrode the addition of a point | ||
// (in the case of teleport portals) | ||
m_fields->prev_position = current_position; | ||
} | ||
} | ||
|
||
// teleport portal | ||
void resetStreak() { | ||
m_fields->dont_add = true; | ||
PlayerObject::resetStreak(); | ||
} | ||
if (LevelEditorLayer::get()) return; | ||
if (!m_isDart || m_isHidden) { | ||
m_fields->previousPos = m_fields->currentPos; | ||
return; | ||
} | ||
|
||
CCPoint previousPosition = m_fields->previousPos; | ||
CCPoint currentPosition = m_fields->currentPos; | ||
CCPoint nextPositionNoCollision = m_fields->nextPosNoCollision; | ||
CCPoint nextPosition = getRealPosition(); | ||
|
||
if (m_fields->forceAdd && !m_fields->forceAddSpiderRing) { | ||
m_fields->forceAdd = false; | ||
m_waveTrail->addPoint(currentPosition); | ||
m_fields->previousPos = currentPosition; | ||
return; | ||
} else if (m_fields->forceAddSpiderRing && !m_fields->justTeleported) { | ||
// spider orb require special care so the line looks straight | ||
m_fields->forceAddSpiderRing = false; | ||
m_fields->forceAdd = false; | ||
m_fields->transitionToCollision = false; | ||
m_fields->teleportedPreviously = false; | ||
CCPoint pointToAdd = m_isSideways ? CCPoint{nextPosition.x, previousPosition.y} : CCPoint{previousPosition.x, nextPosition.y}; | ||
m_waveTrail->addPoint(pointToAdd); | ||
m_fields->previousPos = pointToAdd; | ||
return; | ||
} else if (m_fields->justTeleported) { | ||
// if we just teleported, we set a streak point to the portal's position and save its location | ||
// we need to place a new point if we are clicking a spider orb and teleporting at the same time | ||
// as well | ||
m_fields->justTeleported = false; | ||
m_fields->teleportedPreviously = m_fields->forceAddSpiderRing; | ||
m_fields->forceAddSpiderRing = false; | ||
m_fields->forceAdd = false; | ||
m_fields->portalTargetLine = m_isSideways ? previousPosition.y : previousPosition.x; | ||
m_waveTrail->addPoint(previousPosition); | ||
return; | ||
} else if (m_fields->teleportedPreviously) { | ||
m_fields->teleportedPreviously = false; | ||
CCPoint pointToAdd = m_isSideways ? CCPoint{nextPosition.x, m_fields->portalTargetLine} : CCPoint{m_fields->portalTargetLine, nextPosition.y}; | ||
m_waveTrail->addPoint(pointToAdd); | ||
m_fields->previousPos = pointToAdd; | ||
return; | ||
} | ||
cocos2d::CCPoint currentVector = nextPosition - currentPosition; | ||
cocos2d::CCPoint previousVector = currentPosition - previousPosition; | ||
float crossProductMagnitude = abs(currentVector.cross(previousVector)); | ||
|
||
void doReversePlayer(bool p0) { | ||
m_fields->force_add = true; | ||
PlayerObject::doReversePlayer(p0); | ||
} | ||
// save the current point as prevPoint only if it is placed as a streak point | ||
// this makes it so that even smooth paths where | ||
// any 3 consecutive points may look like a straight line | ||
// still get marked for new point addition, because | ||
// we are no longer checking for 3 consecutive points | ||
// this accounts for the wave going in very changing smooth curves | ||
// but one issue is that the cumulative error eventually gets large enough | ||
// that a point is placed even when moving in a constant direction | ||
// i don't think that can be recreated unless you use the zoom trigger to | ||
// zoom the game out up to a point where you can't even notice that extra point anymore though | ||
// basically, this trades off accounting for one type of cumulative error | ||
// (slowly moving smooth transitions not being detected as actually changing moving) | ||
// over another (the an unchanged direction being detected as a change in direction over a long period of time) | ||
|
||
void placeStreakPoint() { if (!m_isDart || !m_gameLayer) PlayerObject::placeStreakPoint(); } | ||
if (crossProductMagnitude > 0.01 && !m_fields->dontAdd) { | ||
if (nextPosition != nextPositionNoCollision && !m_fields->transitionToCollision) { | ||
if (m_isSideways) { | ||
std::swap(nextPositionNoCollision.x, nextPositionNoCollision.y); | ||
std::swap(nextPosition.x, nextPosition.y); | ||
std::swap(currentPosition.x, currentPosition.y); | ||
} | ||
float intercept = (nextPositionNoCollision.y - currentPosition.y)/(nextPositionNoCollision.x - currentPosition.x); | ||
float desiredValue = (nextPosition.y - currentPosition.y + intercept * currentPosition.x)/intercept; | ||
if ((desiredValue < currentPosition.x && !m_isGoingLeft) || (desiredValue > currentPosition.x && m_isGoingLeft)) | ||
desiredValue = currentPosition.x; | ||
CCPoint intersectionPoint{desiredValue, nextPosition.y}; | ||
if (m_isSideways) { | ||
std::swap(nextPositionNoCollision.x, nextPositionNoCollision.y); | ||
std::swap(nextPosition.x, nextPosition.y); | ||
std::swap(currentPosition.x, currentPosition.y); | ||
std::swap(intersectionPoint.x, intersectionPoint.y); | ||
} | ||
m_waveTrail->addPoint(intersectionPoint); | ||
m_fields->previousPos = intersectionPoint; | ||
m_fields->transitionToCollision = true; | ||
} else if (nextPosition == nextPositionNoCollision) { | ||
m_fields->transitionToCollision = false; | ||
m_waveTrail->addPoint(currentPosition); | ||
m_fields->previousPos = currentPosition; | ||
} else { | ||
m_waveTrail->addPoint(currentPosition); | ||
m_fields->previousPos = currentPosition; | ||
} | ||
} else if (m_fields->dontAdd) { | ||
m_fields->dontAdd = false; | ||
m_fields->previousPos = currentPosition; | ||
return; | ||
} | ||
} | ||
|
||
// spider orb | ||
void pushButton(PlayerButton p0) { | ||
const int TOGGLE_RING = 1594; | ||
const int TELEPORT_RING = 3027; | ||
const int SPIDER_RING = 3004; | ||
if (!m_isDart || !m_gameLayer || LevelEditorLayer::get()) return PlayerObject::pushButton(p0); | ||
bool willTriggerSpiderRing = false; | ||
|
||
for (size_t i = 0; i < m_touchingRings->count(); i++) { | ||
RingObject *ring = static_cast<RingObject *>(m_touchingRings->objectAtIndex(i)); | ||
switch (ring->m_objectID) { | ||
// these 2 seem to allow the click to reach the next ring | ||
case TOGGLE_RING: // fallthrough | ||
if (ring->m_claimTouch) return PlayerObject::pushButton(p0); | ||
case TELEPORT_RING: | ||
continue; | ||
case SPIDER_RING: // fallthrough | ||
willTriggerSpiderRing = true; // will trigger unless a toggle ring claims the touch | ||
default: | ||
if (!willTriggerSpiderRing) return PlayerObject::pushButton(p0); | ||
} | ||
} | ||
if (willTriggerSpiderRing) { | ||
m_waveTrail->addPoint(m_fields->currentPos); | ||
m_fields->previousPos = m_fields->currentPos; | ||
m_fields->forceAddSpiderRing = true; | ||
} | ||
PlayerObject::pushButton(p0); | ||
} | ||
|
||
void toggleVisibility(bool p0) { | ||
bool needs_point = m_isHidden; | ||
PlayerObject::toggleVisibility(p0); | ||
if (p0 && m_isDart && needs_point && !LevelEditorLayer::get()) m_fields->force_add = true; | ||
} | ||
void doReversePlayer(bool p0) { | ||
m_fields->forceAdd = true; | ||
PlayerObject::doReversePlayer(p0); | ||
} | ||
|
||
void placeStreakPoint() { if (!m_isDart || !m_gameLayer) PlayerObject::placeStreakPoint(); } | ||
|
||
void toggleVisibility(bool p0) { | ||
bool needsPoint = m_isHidden; | ||
PlayerObject::toggleVisibility(p0); | ||
if (p0 && m_isDart && needsPoint) m_fields->forceAdd = true; | ||
} | ||
}; | ||
|
||
class $modify(PlayLayer) { | ||
void playEndAnimationToPos(CCPoint p0) { | ||
if (m_player1 && m_player1->m_isDart) | ||
m_player1->m_waveTrail->addPoint(m_player1->m_position); | ||
if (m_player2 && m_player2->m_isDart) | ||
m_player2->m_waveTrail->addPoint(m_player2->m_position); | ||
PlayLayer::playEndAnimationToPos(p0); | ||
} | ||
void playEndAnimationToPos(CCPoint p0) { | ||
if (m_player1 && m_player1->m_isDart) | ||
m_player1->m_waveTrail->addPoint(m_player1->m_position); | ||
if (m_player2 && m_player2->m_isDart) | ||
m_player2->m_waveTrail->addPoint(m_player2->m_position); | ||
PlayLayer::playEndAnimationToPos(p0); | ||
} | ||
}; | ||
|
||
// teleport portal | ||
class $modify(GJBaseGameLayer) { | ||
void teleportPlayer(TeleportPortalObject *portal, PlayerObject *player) { | ||
GJBaseGameLayer::teleportPlayer(portal, player); | ||
CCPoint targetPos = getPortalTargetPos(portal, getPortalTarget(portal), player); | ||
static_cast<WTDFPlayerObject *>(player)->m_fields->previousPos = targetPos; | ||
static_cast<WTDFPlayerObject *>(player)->m_fields->justTeleported = true; | ||
static_cast<WTDFPlayerObject *>(player)->m_fields->dontAdd = true; | ||
} | ||
}; |