Skip to content

Commit

Permalink
feat(enhancement): Allow GameActions to give the player debt (endless…
Browse files Browse the repository at this point in the history
  • Loading branch information
Amazinite authored May 18, 2024
1 parent e96054d commit 954b814
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 17 deletions.
41 changes: 31 additions & 10 deletions source/Account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ string Account::Step(int64_t assets, int64_t salaries, int64_t maintenance)
// or skipped completely (accruing interest and reducing your credit score).
int64_t mortgagesPaid = 0;
int64_t finesPaid = 0;
int64_t debtPaid = 0;
for(Mortgage &mortgage : mortgages)
{
int64_t payment = mortgage.Payment();
Expand All @@ -221,11 +222,13 @@ string Account::Step(int64_t assets, int64_t salaries, int64_t maintenance)
{
payment = mortgage.MakePayment();
credits -= payment;
// For the status text, keep track of whether this is a mortgage or a fine.
// For the status text, keep track of whether this is a mortgage, fine, or debt.
if(mortgage.Type() == "Mortgage")
mortgagesPaid += payment;
else
else if(mortgage.Type() == "Fine")
finesPaid += payment;
else
debtPaid += payment;
}
assets -= mortgage.Principal();
}
Expand All @@ -249,7 +252,7 @@ string Account::Step(int64_t assets, int64_t salaries, int64_t maintenance)
creditScore = max(200, min(800, creditScore + (missedPayment ? -5 : 1)));

// If you didn't make any payments, no need to continue further.
if(!(salariesPaid + maintenancePaid + mortgagesPaid + finesPaid))
if(!(salariesPaid + maintenancePaid + mortgagesPaid + finesPaid + debtPaid))
return out.str();
else if(missedPayment)
out << " ";
Expand All @@ -265,6 +268,8 @@ string Account::Step(int64_t assets, int64_t salaries, int64_t maintenance)
typesPaid["mortgages"] = mortgagesPaid;
if(finesPaid)
typesPaid["fines"] = finesPaid;
if(debtPaid)
typesPaid["debt"] = debtPaid;

// If you made payments of three or more types, the punctuation needs to
// include commas, so just handle that separately here.
Expand All @@ -282,15 +287,18 @@ string Account::Step(int64_t assets, int64_t salaries, int64_t maintenance)
{
if(salariesPaid)
out << Format::CreditString(salariesPaid) << " in crew salaries"
<< ((mortgagesPaid || finesPaid || maintenancePaid) ? " and " : ".");
<< ((mortgagesPaid || finesPaid || debtPaid || maintenancePaid) ? " and " : ".");
if(maintenancePaid)
out << Format::CreditString(maintenancePaid) << " in maintenance"
<< ((mortgagesPaid || finesPaid) ? " and " : ".");
<< ((mortgagesPaid || finesPaid || debtPaid) ? " and " : ".");
if(mortgagesPaid)
out << Format::CreditString(mortgagesPaid) << " in mortgages"
<< (finesPaid ? " and " : ".");
<< ((finesPaid || debtPaid) ? " and " : ".");
if(finesPaid)
out << Format::CreditString(finesPaid) << " in fines.";
out << Format::CreditString(finesPaid) << " in fines"
<< (debtPaid ? " and " : ".");
if(debtPaid)
out << Format::CreditString(debtPaid) << " in debt.";
}
return out.str();
}
Expand Down Expand Up @@ -373,7 +381,7 @@ const vector<Mortgage> &Account::Mortgages() const
// your credit score.
void Account::AddMortgage(int64_t principal)
{
mortgages.emplace_back(principal, creditScore);
mortgages.emplace_back("Mortgage", principal, creditScore);
credits += principal;
}

Expand All @@ -382,7 +390,19 @@ void Account::AddMortgage(int64_t principal)
// Add a "fine" with a high, fixed interest rate and a short term.
void Account::AddFine(int64_t amount)
{
mortgages.emplace_back(amount, 0, 60);
mortgages.emplace_back("Fine", amount, 0, 60);
}



// Add debt with the given interest rate and term. If no interest rate is
// given then the player's credit score is used to determine the interest rate.
void Account::AddDebt(int64_t amount, optional<double> interest, int term)
{
if(interest)
mortgages.emplace_back("Debt", amount, *interest, term);
else
mortgages.emplace_back("Debt", amount, creditScore, term);
}


Expand Down Expand Up @@ -424,7 +444,8 @@ int Account::CreditScore() const



// Get the total amount owed for "Mortgage", "Fine", or both.
// Get the total amount owed for a specific type of mortgage, or all
// mortgages if a blank string is provided.
int64_t Account::TotalDebt(const string &type) const
{
int64_t total = 0;
Expand Down
5 changes: 4 additions & 1 deletion source/Account.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.

#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <vector>

Expand Down Expand Up @@ -60,13 +61,15 @@ class Account {
const std::vector<Mortgage> &Mortgages() const;
void AddMortgage(int64_t principal);
void AddFine(int64_t amount);
void AddDebt(int64_t amount, std::optional<double> interest, int term);
int64_t Prequalify() const;
// Assets:
int64_t NetWorth() const;

// Find out the player's credit rating.
int CreditScore() const;
// Get the total amount owed for "Mortgage", "Fine", or both.
// Get the total amount owed for a specific type of mortgage, or all
// mortgages if a blank string is provided.
int64_t TotalDebt(const std::string &type = "") const;


Expand Down
30 changes: 30 additions & 0 deletions source/GameAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ void GameAction::LoadSingle(const DataNode &child)
else
child.PrintTrace("Error: Skipping invalid \"fine\" with non-positive value:");
}
else if(key == "debt" && hasValue)
{
GameAction::Debt &debtEntry = debt.emplace_back(max<int64_t>(0, child.Value(1)));
for(const DataNode &grand : child)
{
const string &grandKey = grand.Token(0);
bool grandHasValue = (grand.Size() > 1);
if(grandKey == "term" && grandHasValue)
debtEntry.term = max<int>(1, grand.Value(1));
else if(grandKey == "interest" && grandHasValue)
debtEntry.interest = clamp(grand.Value(1), 0., 0.999);
else
grand.PrintTrace("Error: Skipping unrecognized \"debt\" attribute:");
}
}
else if(key == "event" && hasValue)
{
int minDays = (child.Size() >= 3 ? child.Value(2) : 1);
Expand Down Expand Up @@ -240,6 +255,17 @@ void GameAction::Save(DataWriter &out) const
out.Write("payment", payment);
if(fine)
out.Write("fine", fine);
for(auto &&debtEntry : debt)
{
out.Write("debt", debtEntry.amount);
out.BeginChild();
{
if(debtEntry.interest)
out.Write("interest", *debtEntry.interest);
out.Write("term", debtEntry.term);
}
out.EndChild();
}
for(auto &&it : events)
out.Write("event", it.first->Name(), it.second.first, it.second.second);
for(const string &name : fail)
Expand Down Expand Up @@ -363,6 +389,8 @@ void GameAction::Do(PlayerInfo &player, UI *ui, const Mission *caller) const
}
if(fine)
player.Accounts().AddFine(fine);
for(const auto &debtEntry : debt)
player.Accounts().AddDebt(debtEntry.amount, debtEntry.interest, debtEntry.term);

for(const auto &it : events)
player.AddEvent(*it.first, player.GetDate() + it.second.first);
Expand Down Expand Up @@ -424,6 +452,8 @@ GameAction GameAction::Instantiate(map<string, string> &subs, int jumps, int pay
if(result.fine)
subs["<fine>"] = Format::CreditString(result.fine);

result.debt = debt;

if(!logText.empty())
result.logText = Format::Replace(logText, subs);
for(auto &&it : specialLogText)
Expand Down
11 changes: 11 additions & 0 deletions source/GameAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ class GameAction {
GameAction Instantiate(std::map<std::string, std::string> &subs, int jumps, int payload) const;


private:
struct Debt {
Debt(int64_t amount) : amount(amount) {}

int64_t amount = 0;
std::optional<double> interest;
int term = 365;
};


private:
bool isEmpty = true;
std::string logText;
Expand All @@ -87,6 +97,7 @@ class GameAction {
int64_t payment = 0;
int64_t paymentMultiplier = 0;
int64_t fine = 0;
std::vector<Debt> debt;

std::optional<std::string> music;

Expand Down
21 changes: 18 additions & 3 deletions source/Mortgage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ int64_t Mortgage::Maximum(int64_t annualRevenue, int creditScore, double current


// Create a new mortgage of the given amount.
Mortgage::Mortgage(int64_t principal, int creditScore, int term)
: type(creditScore <= 0 ? "Fine" : "Mortgage"),
Mortgage::Mortgage(string type, int64_t principal, int creditScore, int term)
: type(std::move(type)),
principal(principal),
interest((600 - creditScore / 2) * .00001),
interestString("0." + to_string(600 - creditScore / 2) + "%"),
Expand All @@ -57,6 +57,20 @@ Mortgage::Mortgage(int64_t principal, int creditScore, int term)



// Create a mortgage with a specific interest rate instead of using the player's
// credit score. Due to how the class is set up, the interest rate must currently
// be within the range [0, 1).
Mortgage::Mortgage(string type, int64_t principal, double interest, int term)
: type(std::move(type)),
principal(principal),
interest(interest * .01),
interestString("0." + to_string(static_cast<int>(1000. * interest)) + "%"),
term(term)
{
}



// Construct and Load() at the same time.
Mortgage::Mortgage(const DataNode &node)
{
Expand Down Expand Up @@ -138,7 +152,8 @@ int64_t Mortgage::PayExtra(int64_t amount)


// The type is "Mortgage" if this is a mortgage you applied for from a bank,
// and "Fine" if this is a fine imposed on you for illegal activities.
// "Fine" if this is a fine imposed on you for illegal activities, and
// "Debt" if this is debt given to you by a mission.
const string &Mortgage::Type() const
{
return type;
Expand Down
9 changes: 7 additions & 2 deletions source/Mortgage.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ class Mortgage {
Mortgage() = default;
// Create a new mortgage of the given amount. If this is a fine, set the
// credit score to zero for a higher interest rate.
Mortgage(int64_t principal, int creditScore, int term = 365);
Mortgage(std::string type, int64_t principal, int creditScore, int term = 365);
// Create a mortgage with a specific interest rate instead of using the player's
// credit score. Due to how the class is set up, the interest rate must currently
// be within the range [0, 1).
Mortgage(std::string type, int64_t principal, double interest, int term = 365);
// Construct and Load() at the same time.
Mortgage(const DataNode &node);

Expand All @@ -58,7 +62,8 @@ class Mortgage {
int64_t PayExtra(int64_t amount);

// The type is "Mortgage" if this is a mortgage you applied for from a bank,
// and "Fine" if this is a fine imposed on you for illegal activities.
// "Fine" if this is a fine imposed on you for illegal activities, and
// "Debt" if this is debt given to you by a mission.
const std::string &Type() const;
// Get the remaining mortgage principal.
int64_t Principal() const;
Expand Down
4 changes: 4 additions & 0 deletions source/PlayerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3177,6 +3177,10 @@ void PlayerInfo::RegisterDerivedConditions()
unpaidFinesProvider.SetGetFunction([this](const string &name) {
return min(limit, accounts.TotalDebt("Fine")); });

auto &&unpaidDebtsProvider = conditions.GetProviderNamed("unpaid debts");
unpaidDebtsProvider.SetGetFunction([this](const string &name) {
return min(limit, accounts.TotalDebt("Debt")); });

auto &&unpaidSalariesProvider = conditions.GetProviderNamed("unpaid salaries");
unpaidSalariesProvider.SetGetFunction([this](const string &name) {
return min(limit, accounts.CrewSalariesOwed()); });
Expand Down
2 changes: 1 addition & 1 deletion source/Ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2979,7 +2979,7 @@ double Ship::MaxVelocity(bool withAfterburner) const
// v = thrust / drag
double thrust = attributes.Get("thrust");
double afterburnerThrust = attributes.Get("afterburner thrust");
return (thrust ? thrust + afterburnerThrust * withAfterburner: afterburnerThrust) / Drag();
return (thrust ? thrust + afterburnerThrust * withAfterburner : afterburnerThrust) / Drag();
}


Expand Down

0 comments on commit 954b814

Please sign in to comment.