#include "rulemodule.h" #include #include #include #include #include "math.h" #include "common/scssdk_telemetry_common_gameplay_events.h" double peakedSine(double x, double peakTime = 0.2) { double stretchedX; if (x < peakTime) stretchedX = x / (peakTime*2.0); else stretchedX = 0.5+( ( (x-peakTime)/(1-peakTime) )*0.5 ); double ret = 1.0-((1.0+(std::cos(stretchedX * M_PI * 2.0)))/2.0); qDebug() << "peakedSine(" << x << ") =" << ret; return ret; } RuleModule::RuleModule(QObject *parent) : QObject{parent} { // const QMetaObject* meta = metaObject(); // for (int idx = 1; idx < meta->propertyCount(); idx++) // { // QMetaProperty prop = meta->property(idx); // connect(this, prop.notifySignal(), this, [&]()); // } } void RuleModule::save(QSettings& settings) const { const QMetaObject* meta = metaObject(); settings.beginGroup(objectName()); for (int idx = 1; idx < meta->propertyCount(); idx++) { QMetaProperty prop = meta->property(idx); QVariant value = prop.read(this); qDebug() << "Saving settings: " << objectName() << "/" << prop.name() << " = " << value; settings.setValue(prop.name(), value); } settings.endGroup(); } void RuleModule::load(QSettings& settings) { const QMetaObject* meta = metaObject(); settings.beginGroup(objectName()); for (int idx = 1; idx < meta->propertyCount(); idx++) { QMetaProperty prop = meta->property(idx); QVariant value = settings.value(prop.name(), prop.read(this)); qDebug() << "Loading settings: " << objectName() << "/" << prop.name() << " = " << value; prop.write(this, value); emit prop.notifySignal(); } settings.endGroup(); } double SpeedModule::process(const TelemetryState& telemetry, double previous, double delta) { double ret = previous; if (Enabled && TopSpeed > 0) { double speedN = std::abs(telemetry.speed * 3.6) / TopSpeed; sine_x += delta * speedN; double sine = std::sin(sine_x * WaveFrequency * M_PI * 2); double power = std::clamp(speedN + (sine * speedN * WaveAmplitude), 0.0, 1.0); ret += power * MaxOutput; } return ret; } double RPMModule::process(const TelemetryState& telemetry, double previous, double delta) { double ret = previous; if (Enabled && (TopRPM - BottomRPM) > 0) { double rpmN = (telemetry.rpm - BottomRPM) / (TopRPM - BottomRPM); ret += rpmN * MaxOutput; } return ret; } void CrimeModule::gameEvent(const QString name, const QMap attributes) { if (name == SCS_TELEMETRY_GAMEPLAY_EVENT_player_fined) { if (attributes.contains(SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_amount)) { uint64_t amount = attributes[SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_amount].toULongLong(); timeout += amount * SecondsPerEuro; } if (attributes.contains(SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_offence)) { QString offence = attributes[SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_offence].toString(); // You... if (offence == "crash") whatYouDid = "killed someone"; else if (offence == "red_signal") whatYouDid = "ran a red light"; else if (offence == "avoid_sleeping") whatYouDid = "were caught being eepy"; else if (offence == "speeding_camera") whatYouDid = "got flashed"; else if (offence == "no_lights") whatYouDid = "forgot to press the headlight button twice"; // else if (offence == "speeding") // whatYouDid = ""; // else if (offence == "avoid_weighing") // whatYouDid = ""; else if (offence == "illegal_trailer") whatYouDid = "got found packing heat"; else if (offence == "avoid_inspection") whatYouDid = "missed penis inspection day"; // else if (offence == "illegal_border_crossing") // whatYouDid = ""; // else if (offence == "hard_shoulder_violation") // whatYouDid = ""; // else if (offence == "damaged_vehicle_usage") // whatYouDid = ""; else if (offence == "generic") whatYouDid = "failed the vibe check"; else whatYouDid = "broke the law"; // ...! You'll be punished for X seconds! } } } double CrimeModule::process(const TelemetryState& telemetry, double previous, double delta) { double ret = previous; if (Enabled) { if (timeout > 0.0) { timeout -= delta; ret *= PowerMultiplier; emit statusUpdate(QString("You %2! You'll be punished for %1 seconds!").arg(timeout, 0, 'f', 1).arg(whatYouDid)); } } return ret; } void JobModule::gameEvent(const QString name, const QMap attributes) { if (name == SCS_TELEMETRY_GAMEPLAY_EVENT_job_delivered) { totalTime = 0.0; if (attributes.contains(SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_revenue)) { uint64_t amount = attributes[SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_revenue].toULongLong(); totalTime += (amount/100.0) * SecondsPerEuro; } if (attributes.contains(SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_earned_xp)) { uint64_t amount = attributes[SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_earned_xp].toULongLong(); totalTime += (amount/100.0) * SecondsPerXP; } timeout = totalTime; } } double JobModule::process(const TelemetryState& telemetry, double previous, double delta) { double ret = previous; if (Enabled) { if (timeout > 0.0) { timeout -= delta; ret += peakedSine((totalTime-timeout)/totalTime, 0.1) * PowerBoost; emit statusUpdate(QString("Well done! You'll be rewarded for %1 seconds!").arg(timeout, 0, 'f', 1)); } } return ret; } double DistanceModule::process(const TelemetryState& telemetry, double previous, double delta) { double ret = previous; if (Enabled) { if (telemetry.distance > nextReward) { double random = (1.0 - Randomness) + (QRandomGenerator::global()->generateDouble() * 2.0 * Randomness); qDebug () << "Random factor: " << random; double distanceToNext = Distance * 1000.0 * random; timeout = Duration; nextReward += distanceToNext; qDebug() << "Next distance reward will be in " << distanceToNext << " metres, at " << nextReward; } if (timeout > 0.0) { timeout -= delta; ret += peakedSine((Duration-timeout)/Duration, 0.4) * PowerBoost; emit statusUpdate(QString("You've driven so far! You'll be rewarded for %1 seconds!").arg(timeout, 0, 'f', 1)); } } return ret; }