Skip to content
This repository has been archived by the owner on Jul 8, 2020. It is now read-only.

Commit

Permalink
Add "Change Cyrus Customisation Time" Patch
Browse files Browse the repository at this point in the history
Can have items instantly completed.
Or can change the time it takes to complete.
Credit to Poyo for save offsets used to make this :)
  • Loading branch information
Slattz committed Oct 18, 2019
1 parent 2e3404a commit cd270a4
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 42 deletions.
104 changes: 76 additions & 28 deletions Forms/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget_exefs">
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="tab_exefs_general">
<attribute name="title">
Expand Down Expand Up @@ -709,19 +709,6 @@
<string>Shops</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="5" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="CB_ReeseBuy">
<property name="toolTip">
Expand All @@ -732,27 +719,53 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="CB_LeilaBuy">
<item row="1" column="0">
<widget class="QCheckBox" name="CB_NooklingBuy">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;On the island, Leila originally buys items for 1/80 of the price they'll be sold at. With this code enabled, Leila will buy items for their sell price.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The Nooklings originally buys items for of the price they'll be sold at. With this enabled, the Nooklings will buy items for their sell price.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Leila Buys Items For Their Sell Price</string>
<string>Nooklings Buy Items For Their Sell Price</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="CB_NooklingBuy">
<item row="3" column="0">
<widget class="QCheckBox" name="CB_NativeFruitSellPrice">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The Nooklings originally buys items for ⅕ of the price they'll be sold at. With this enabled, the Nooklings will buy items for their sell price.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enabling this makes shops pay the same price for native fruit as they do for foreign fruit.&lt;/p&gt;&lt;p&gt;E.g. If oranges was your native fruit, 1 orange will now sell for 500 bells instead of 100 bells.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Nooklings Buy Items For Their Sell Price</string>
<string>Shops Buy Native Fruit For Same Price As Foreign Fruit</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="4" column="0">
<widget class="QCheckBox" name="CB_CyrusCustoms">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This patch allows you to change the time it takes for Cyrus to customise an item. This patch behaves differently depending on the state of the checkbox:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked&lt;/span&gt;: No changes.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Partially Checked&lt;/span&gt;: Items are instantly customised and can be collected right after giving to Cyrus.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Fully Checked&lt;/span&gt;: You can instead specify a custom time (in seconds) it takes for items to get customised.&lt;/p&gt;&lt;p&gt;Credit to Poyo for the save offsets used to create this patch :)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Change Cyrus Customisation Time</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="2" colspan="2">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="BTN_ShopTimes">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This allows you to customise the opening hours of shops to your liking!&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
Expand All @@ -762,17 +775,17 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="CB_NativeFruitSellPrice">
<item row="2" column="0">
<widget class="QCheckBox" name="CB_LeilaBuy">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enabling this makes shops pay the same price for native fruit as they do for foreign fruit.&lt;/p&gt;&lt;p&gt;E.g. If oranges was your native fruit, 1 orange will now sell for 500 bells instead of 100 bells.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;On the island, Leila originally buys items for 1/80 of the price they'll be sold at. With this code enabled, Leila will buy items for their sell price.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;This may only be visible to you and not other players.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Shops Buy Native Fruit For Same Price As Foreign Fruit</string>
<string>Leila Buys Items For Their Sell Price</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="6" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -785,6 +798,41 @@
</property>
</spacer>
</item>
<item row="5" column="1" colspan="3">
<widget class="QLabel" name="LBL_CustomiseParsed">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text">
<string>Days: 00 | Hours: 00 | Mins: 25 | Seconds: 00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLineEdit" name="LE_CustomiseSeconds">
<property name="enabled">
<bool>false</bool>
</property>
<property name="inputMask">
<string>999999</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>Enter Amount In Seconds (Default Is 1500).</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_exefs_utils">
Expand Down
5 changes: 3 additions & 2 deletions Headers/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ private slots:
void on_actionAbout_triggered();
void on_BTN_Remapper_clicked();
void on_BTN_ItemPriceChanger_clicked();
void on_dial_CameraZoomOut_valueChanged(int value);
void on_CB_CyrusCustoms_stateChanged(int arg1);
void on_LE_CustomiseSeconds_textChanged(const QString &arg1);

/* Debug Stuff */
void on_actionEnableAll_triggered();
void on_actionListItemPrices_triggered();
void on_actionSetup_OutDir_triggered();
void on_actionQuick_Open_EUR_triggered();

void on_dial_CameraZoomOut_valueChanged(int value);

private:
Ui::MainWindow *ui = nullptr;
QString dir = "\0";
Expand Down
12 changes: 8 additions & 4 deletions Headers/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,7 @@ extern Patch CmdKeyboard_ChangeTime;
extern Patch CmdKeyboard_DupeAll;
extern Patch CmdKeyboard_ClearInv;

extern Patch NativeFruitPrice;
extern Patch ReeseBuy;
extern Patch NooklingsBuy;
extern Patch LeilaBuy;
/* Exefs->General */
extern Patch Confetti;
extern Patch CherryBlossom;
extern Patch Weather;
Expand Down Expand Up @@ -172,6 +169,13 @@ extern Patch InstantText;
extern Patch CameraZoomOut;
extern Patch CmdKeyboardHook;

/* Exefs->Shops */
extern Patch NativeFruitPrice;
extern Patch ReeseBuy;
extern Patch NooklingsBuy;
extern Patch LeilaBuy;
extern Patch InstantCyrusCustoms;

/* Shop Times: Addresses are start of function */
extern Patch Retail;
extern Patch Nooklings;
Expand Down
10 changes: 10 additions & 0 deletions Sources/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,16 @@ bool Game::ApplyPatches(Ui::MainWindow *mainui, File *codebin) {
if(mainui->CB_LeilaBuy->isChecked())
res |= LeilaBuy.Apply(codebin);

if (mainui->CB_CyrusCustoms->checkState() == Qt::Checked) { //Can do custom time
bool success = false;
quint32 val = mainui->CB_CyrusCustoms->text().toUInt(&success, 10);
res |= !PatchCode(codebin, InstantCyrusCustoms.m_Offset+0xF4, (success == true ? val : 1500));
}

else if (mainui->CB_CyrusCustoms->checkState() == Qt::PartiallyChecked) { //Instant customisation
res |= InstantCyrusCustoms.Apply(codebin);
}

/* Exefs->Utilities */
if(mainui->CB_RegionPass->isChecked())
res |= RegionCheck.Apply(codebin);
Expand Down
29 changes: 29 additions & 0 deletions Sources/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,35 @@ void MainWindow::on_dial_CameraZoomOut_valueChanged(int value)
}


void MainWindow::on_CB_CyrusCustoms_stateChanged(int arg1)
{
ui->LE_CustomiseSeconds->setEnabled(false); //Nothing or Instant Unlock (nocheck or partially checked)

if (arg1 == Qt::Checked) { //Custom value
ui->LE_CustomiseSeconds->setEnabled(true);
}
}

void MainWindow::on_LE_CustomiseSeconds_textChanged(const QString &arg1)
{
static constexpr char lblText[] = "Days: %02d | Hours: %02d | Mins: %02d | Seconds: %02d";
bool res = false;
quint32 days = 0, hours = 0, mins = 0, secs = 1;
quint32 val = arg1.toUInt(&res, 10);

if (res == true) {
secs = val%60;
mins = val/(60);
hours = mins/60;
mins %= 60;
days = hours/24;
hours%= 24;
}

ui->LBL_CustomiseParsed->setText(QString::asprintf(lblText, days,hours,mins,secs));
}


/* Debug Stuff */
void MainWindow::on_actionEnableAll_triggered()
{
Expand Down
29 changes: 21 additions & 8 deletions Sources/patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ static const QVector<quint8> Permit100Pattern2 = { //+0x8
0x81, 0x10, 0x82, 0xE1, 0x07, 0x30, 0xCC, 0xE3
};

static const QVector<quint8> InstantCyrusCustomsPattern = { //+0
0x03, 0x70, 0xA0, 0xE1, 0x27, 0x00, 0x00, 0x2A,
0x04, 0x20, 0x85, 0xE0, 0x01, 0x00, 0xA0, 0xE3
};

//Check if button is newly pressed
static const QVector<quint8> hidKeysDownPattern = { // -0x30 for function start
0x00, 0x00, 0xA0, 0x93, 0x04, 0x00, 0x90, 0xE5,
Expand Down Expand Up @@ -348,10 +353,6 @@ Patch CmdKeyboard_DupeAll;
Patch CmdKeyboard_ClearInv;

/* Exefs->General */
Patch NativeFruitPrice;
Patch ReeseBuy;
Patch NooklingsBuy;
Patch LeilaBuy;
Patch Confetti; //Pattern: 16 5B 84 E2 AC 50 85 E2 00 00 95 E5 00 00 50 E3 + 0x8
Patch CherryBlossom; //Pattern: 10 D0 4D E2 02 00 A0 E3 16 6B 84 E2 AC 60 86 E2 + 0x8
Patch Weather; //Pattern: 1st find of [06 10 41 E2 00 00 51 E3 18 10 81 B2 34 00 50 E3] + 0x88
Expand Down Expand Up @@ -390,6 +391,13 @@ Patch InstantText; //Pattern: 08 10 8D E5 08 10 8D E2 04 00 A0 E1 + 0x48
Patch CameraZoomOut; //Float; Pattern: 05 1A C0 ED 06 0A 80 ED 0A 1A 80 ED 0B 3A C0 ED 1E FF 2F E1 + 0x14
Patch CmdKeyboardHook;

/* Exefs->Shops */
Patch NativeFruitPrice;
Patch ReeseBuy;
Patch NooklingsBuy;
Patch LeilaBuy;
Patch InstantCyrusCustoms; //Pattern: 03 70 A0 E1 27 00 00 2A 04 20 85 E0 01 00 A0 E3 + 0

/* Shop Times: Addresses are start of function */
Patch Retail;
Patch Nooklings; //Pattern: 00 10 A0 E1 14 00 D4 E5 04 40 91 E5
Expand Down Expand Up @@ -539,10 +547,6 @@ void Patch::Init(void) {
qDebug() << "End Button Remap Utils";

/* Exefs->General */
NativeFruitPrice = Patch(0x30576C, 0x3056AC, 0x3056B8, KOR, 0x30576C, 0x305714, 0x3056B8, WAKOR, NOPVec);
ReeseBuy = Patch(0x768EE0, 0x76A740, 0x769748, KOR, 0x768EB8, 0x769724, 0x769720, WAKOR, NOPVec);
NooklingsBuy = Patch(0x769148, 0x76A9A8, 0x7699B0, KOR, 0x769120, 0x76998C, 0x769988, WAKOR, QVector<PatchValues>({{0xE1A041A0, 0}, {NOP, 8}}));
LeilaBuy = Patch(0x768884, 0x76A0E4, 0x7690EC, KOR, 0x76885C, 0x7690C8, 0x7690C4, WAKOR, QVector<PatchValues>({{0xE1A00004,0}}));
Confetti = Patch(ConfettiPattern, QVector<PatchValues>({{0xE3A00001, 0}, {0xE3A00078, 0x30}}), 8);
CherryBlossom = Patch(CherryBPattern, QVector<PatchValues>({{0xE3A00001, 0}, {0xE3A00001, 0x28}, {0xE3A00004, 0x50}, {0xE3A01001, 0x60}}), 0x10);
Weather = Patch(0x62E728, 0x62FC30, 0x62EC68, KOR, 0x62E728, 0x62F158, 0x62EC68, WAKOR, QVector<PatchValues>({{0xE3A00000,0}})); //Pattern: 1st find of [06 10 41 E2 00 00 51 E3 18 10 81 B2 34 00 50 E3] + 0x88
Expand Down Expand Up @@ -585,6 +589,15 @@ void Patch::Init(void) {
CmdKeyboardHook = Patch(CmdKeyboardHookPattern, QVector<PatchValues>({{0xE3A00000, 0}, {0xE3500000, 4}, {0xE59F6064, 8}, {0x15960000, 0xC}}), static_cast<quint32>(-0x10));
qDebug() << "End Exefs->Utilities";

/* Exefs->Shops */
NativeFruitPrice = Patch(0x30576C, 0x3056AC, 0x3056B8, KOR, 0x30576C, 0x305714, 0x3056B8, WAKOR, NOPVec);
ReeseBuy = Patch(0x768EE0, 0x76A740, 0x769748, KOR, 0x768EB8, 0x769724, 0x769720, WAKOR, NOPVec);
NooklingsBuy = Patch(0x769148, 0x76A9A8, 0x7699B0, KOR, 0x769120, 0x76998C, 0x769988, WAKOR, QVector<PatchValues>({{0xE1A041A0, 0}, {NOP, 8}}));
LeilaBuy = Patch(0x768884, 0x76A0E4, 0x7690EC, KOR, 0x76885C, 0x7690C8, 0x7690C4, WAKOR, QVector<PatchValues>({{0xE1A00004,0}}));
InstantCyrusCustoms=Patch(InstantCyrusCustomsPattern, QVector<PatchValues>({{0xE1A07002, 0}, {0xE3A00000, 0xC}}),0);
qDebug() << "End Exefs->Shops";


/* Shop Times: Addresses are start of function */
Retail = Patch(0x309310, 0x30929C, 0x309298, KOR, 0x309310, 0x309384, 0x309298, WAKOR, FFVec);
Nooklings = Patch(0x710054, 0x7118A0, 0x7108A8, KOR, 0x71002C, 0x710D50, 0x710880, WAKOR, FFVec); //Pattern: 00 10 A0 E1 14 00 D4 E5 04 40 91 E5
Expand Down

0 comments on commit cd270a4

Please sign in to comment.