From a934205d087cfb9667bd2c0e9e02eedfee666434 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Thu, 4 May 2017 00:05:48 -0500 Subject: [PATCH] Added crimes mechanic --- index.html | 11 +++-- src/Crimes.js | 116 +++++++++++++++++++++++++++++++++++++++++++++--- src/Faction.js | 14 ++++++ src/Location.js | 55 ++++++++++++++++++----- src/Player.js | 40 ++++++++++++----- src/engine.js | 13 +++++- 6 files changed, 216 insertions(+), 33 deletions(-) diff --git a/index.html b/index.html index 30914e2ef..cb384ee6d 100644 --- a/index.html +++ b/index.html @@ -552,14 +552,17 @@

You have entered the Slums, a poverty-ridden district filled with gangs, criminals, and - other shadowy entities. The city's government and police have neglected this area for years... + other shadowy entities. The city's government and police have neglected this area for years...


+ + In the Slums you can commit crimes to earn money and experience. Crime attempts are not always + successful. Your chance at successfully committing a crime is determined by your stats.

Shoplift Mug someone - Deal drugs - Traffick illegal arms + Deal Drugs + Traffick Illegal Arms Homicide - Kidnap and ransom + Kidnap and Ransom diff --git a/src/Crimes.js b/src/Crimes.js index 402ba4f39..494c77058 100644 --- a/src/Crimes.js +++ b/src/Crimes.js @@ -1,8 +1,110 @@ /* Crimes.js */ - - Shoplift - Mug someone - Deal Drugs - Traffick illegal arms - Homicide - Kidnap and ransom \ No newline at end of file +function commitShopliftCrime() { + Player.crimeType = CONSTANTS.CrimeShoplift; + Player.startCrime(0, 1, 1, 1, 1, 0, 100, 3000); //$33.33 per sec +} + +function commitMugCrime() { + Player.crimeType = CONSTANTS.CrimeMug; + Player.startCrime(0, 2, 2, 2, 2, 0, 250, 5000); //$50 per sec +} + +function commitDealDrugsCrime() { + Player.crimeType = CONSTANTS.CrimeDrugs; + Player.startCrime(0, 2, 2, 2, 2, 5, 1000, 10000); //$100 per sec +} + +function commitTraffickArmsCrime() { + Player.crimeType = CONSTANTS.CrimeTraffickArms; + Player.startCrime(0, 5, 5, 5, 5, 10, 2500, 20000); //$125 per sec +} + +function commitHomicideCrime() { + Player.crimeType = CONSTANTS.CrimeHomicide; + Player.startCrime(0, 20, 20, 20, 20, 0, 300, 3000); //$100 per sec +} + +function commitKidnapCrime() { + Player.crimeType = CONSTANTS.CrimeKidnap; + Player.startCrime(0, 6, 6, 6, 6, 6, 10000, 60000); //$166.67 per sec +} + +function determineCrimeSuccess(crime, moneyGained) { + var chance = 0; + switch (crime) { + case CONSTANTS.CrimeShoplift: + chance = determineCrimeChanceShoplift(); + break; + case CONSTANTS.CrimeMug: + chance = determineCrimeChanceMug(); + break; + case CONSTANTS.CrimeDrugs: + chance = determineCrimeChanceDealDrugs(); + break; + case CONSTANTS.CrimeTraffickArms: + chance = determineCrimeChanceTraffickArms(); + break; + case CONSTANTS.CrimeHomicide: + chance = determineCrimeChanceHomicide(); + break; + case CONSTANTS.CrimeKidnap: + chance = determineCrimeChanceKidnap(); + break; + default: + dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer"); + return; + } + if (Math.random <= chance) { + //Success + Player.gainMoney(moneyGained); + return true; + } else { + //Failure + return false; + } +} + +function determineCrimeChanceShoplift() { + return ((Player.strength / CONSTANTS.MaxSkillLevel + + Player.defense / CONSTANTS.MaxSkillLevel + + Player.dexterity / CONSTANTS.MaxSkillLevel + + Player.agility / CONSTANTS.MaxSkillLevel)) * 10; +} + +function determineCrimeChanceMug() { + return ((Player.strength / CONSTANTS.MaxSkillLevel + + Player.defense / CONSTANTS.MaxSkillLevel + + Player.dexterity / CONSTANTS.MaxSkillLevel + + Player.agility / CONSTANTS.MaxSkillLevel)) * 4; +} + +function determineCrimeChanceDealDrugs() { + return ((3*Player.charisma / CONSTANTS.MaxSkillLevel + + 2*Player.strength / CONSTANTS.MaxSkillLevel + + 2*Player.defense / CONSTANTS.MaxSkillLevel + + 2*Player.dexterity / CONSTANTS.MaxSkillLevel + + 2*Player.agility / CONSTANTS.MaxSkillLevel)); +} + +function determineCrimeChanceTraffickArms() { + return ((Player.charisma / CONSTANTS.MaxSkillLevel + + Player.strength / CONSTANTS.MaxSkillLevel + + Player.defense / CONSTANTS.MaxSkillLevel + + Player.dexterity / CONSTANTS.MaxSkillLevel + + Player.agility / CONSTANTS.MaxSkillLevel)) * 1.5; +} + +function determineCrimeChanceHomicide() { + return ((Player.strength / CONSTANTS.MaxSkillLevel + + Player.defense / CONSTANTS.MaxSkillLevel + + Player.dexterity / CONSTANTS.MaxSkillLevel + + Player.agility / CONSTANTS.MaxSkillLevel)) * 2; +} + +function determineCrimeChanceKidnap() { + return ((Player.charisma / CONSTANTS.MaxSkillLevel + + Player.strength / CONSTANTS.MaxSkillLevel + + Player.defense / CONSTANTS.MaxSkillLevel + + Player.dexterity / CONSTANTS.MaxSkillLevel + + Player.agility / CONSTANTS.MaxSkillLevel)); +} diff --git a/src/Faction.js b/src/Faction.js index 5bedc0806..5d8731df3 100644 --- a/src/Faction.js +++ b/src/Faction.js @@ -771,4 +771,18 @@ displayFactionAugmentations = function(factionName) { augmentationsList.appendChild(item); } +} + +function processPassiveFactionRepGain(numCycles) { + var numTimesGain = numCycles / 600; + for (var name in Factions) { + if (Factions.hasOwnProperty(name)) { + var faction = Factions[name]; + + //TODO Get hard value of 1 rep per "rep gain cycle"" for now.. + //maybe later make this based on + //a player's 'status' like how powerful they are and how much money they have + if (faction.isMember) {faction.playerReputation += numTimesGain;} + } + } } \ No newline at end of file diff --git a/src/Location.js b/src/Location.js index d13de583a..4bc42402b 100644 --- a/src/Location.js +++ b/src/Location.js @@ -58,7 +58,7 @@ Locations = { NewTokyoVitaLife: "VitaLife", NewTokyoGlobalPharmaceuticals: "Global Pharmaceuticals", NewTokyoNoodleBar: "Noodle Bar", - NewTokyoSlums: "New Tokyo Slums" + NewTokyoSlums: "New Tokyo Slums", //Ishima IshimaTravelAgency: "Ishima Travel Agency", @@ -813,13 +813,26 @@ displayLocationContent = function() { case Locations.NewTokyokSlums: case Locations.IshimaSlums: case Locations.VolhavenSlums: + var shopliftChance = determineCrimeChanceShoplift(); + var mugChance = determineCrimeChanceMug(); + var drugsChance = determineCrimeChanceDealDrugs(); + var armsChance = determineCrimeChanceTraffickArms(); + var homicideChance = determineCrimeChanceHomicide(); + var kidnapChance = determineCrimeChanceKidnap(); + slumsDescText.style.display = "block"; slumsShoplift.style.display = "block"; + slumsShoplift.innerHTML = "Shoplift (" + (shopliftChance*100).toFixed(3) + "% chance of success)"; slumsMug.style.display = "block"; + slumsMug.innerHTML = "Mug someone (" + (mugChance*100).toFixed(3) + "% chance of success)"; slumsDealDrugs.style.display = "block"; + slumsDealDrugs.innerHTML = "Deal Drugs (" + (drugsChance*100).toFixed(3) + "% chance of success)"; slumsTrafficArms.style.display = "block"; + slumsTrafficArms.innerHTML = "Traffick Illegal Arms (" + (armsChance*100).toFixed(3) + "% chance of success)"; slumsHomicide.style.display = "block"; + slumsHomicide.innerHTML = "Homicide (" + (homicideChance*100).toFixed(3) + "% chance of success)"; slumsKidnap.style.display = "block"; + slumsKidnap.innerHTML = "Kidnap and Ransom (" + (kidnapChance*100).toFixed(3) + "% chance of success)"; default: console.log("ERROR: INVALID LOCATION"); @@ -1128,7 +1141,7 @@ initLocationButtons = function() { return false; }); - newTokyoSlums = document.getElementByID("newtokyo-slums"); + newTokyoSlums = document.getElementById("newtokyo-slums"); newTokyoSlums.addEventListener("click", function() { Player.location = Locations.NewTokyoSlums; Engine.loadLocationContent(); @@ -1434,15 +1447,35 @@ initLocationButtons = function() { return false; }); - //TODO - /* - var slumsShoplift = document.getElementById("location-slums-shoplift"); - var slumsMug = document.getElementById("location-slums-mug"); - var slumsDealDrugs = document.getElementById("location-slums-deal-drugs"); - var slumsTrafficArms = document.getElementById("location-slums-traffic-arms"); - var slumsHomicide = document.getElementById("location-slums-homicide"); - var slumsKidnap = document.getElementById("location-slums-kidnap"); - */ + slumsShoplift.addEventListener("click", function() { + commitShopliftCrime(); + return false; + }); + + slumsMug.addEventListener("click", function() { + commitMugCrime(); + return false; + }); + + slumsDealDrugs.addEventListener("click", function() { + commitDealDrugsCrime(); + return false; + }); + + slumsTrafficArms.addEventListener("click", function() { + commitTraffickArmsCrime(); + return false; + }); + + slumsHomicide.addEventListener("click", function() { + commitHomicideCrime(); + return false; + }); + + slumsKidnap.addEventListener("click", function() { + commitKidnapCrime(); + return false; + }); } travelToCity = function(destCityName, cost) { diff --git a/src/Player.js b/src/Player.js index 2570f3036..610837d75 100644 --- a/src/Player.js +++ b/src/Player.js @@ -915,7 +915,7 @@ PlayerObject.prototype.finishClass = function() { this.isWorking = false; - Engine.loadTerminalContent(); + Engine.loadLocationContent(); } //The EXP and $ gains are hardcoded. Time is in ms @@ -924,13 +924,13 @@ PlayerObject.prototype.startCrime = function(hackExp, strExp, defExp, dexExp, ag this.isWorking = true; this.workType = CONSTANTS.WorkTypeCrime; - this.workHackExpGained = hackExp; - this.workStrExpGained = strExp; - this.workDefExpGained = defExp; - this.workDexExpGained = dexExp; - this.workAgiExpGained = agiExp; - this.workChaExpGained = chaExp; - this.workMoneyGained = money; + this.workHackExpGained = hackExp * this.hacking_exp_mult; + this.workStrExpGained = strExp * this.strength_exp_mult; + this.workDefExpGained = defExp * this.defense_exp_mult; + this.workDexExpGained = dexExp * this.dexteriy_exp_mult; + this.workAgiExpGained = agiExp * this.agility_exp_mult; + this.workChaExpGained = chaExp * this.charisma_exp_mult; + this.workMoneyGained = money; //TODO multiplier for this? this.timeNeededToCompleteWork = time; @@ -962,7 +962,7 @@ PlayerObject.prototype.finishCrime = function(cancelled) { //Do nothing } else { this.gainWorkExp(); - this.gainMoney(this.workMoneyGained); + //Handle Karma and crime statistics switch(this.crimeType) { @@ -996,10 +996,30 @@ PlayerObject.prototype.finishCrime = function(cancelled) { } } + //Determine crime success/failure + if (determineCrimeSuccess(this.crimeType, this.workMoneyGained)) { + dialogBoxCreate("Crime successful!

" + + "You gained:
"+ + "$" + this.workMoneyGained + "
" + + this.workHackExpGained + " hacking experience
" + + this.workStrExpGained + " strength experience
" + + this.workDefExpGained + " defense experience
" + + this.workDexExpGained + " dexterity experience
" + + this.workAgiExpGained + " agility experience
"); + } else { + dialogBoxCreate("Crime failed!

" + + "You gained:
"+ + this.workHackExpGained + " hacking experience
" + + this.workStrExpGained + " strength experience
" + + this.workDefExpGained + " defense experience
" + + this.workDexExpGained + " dexterity experience
" + + this.workAgiExpGained + " agility experience
"); + } + var mainMenu = document.getElementById("mainmenu-container"); mainMenu.style.visibility = "visible"; this.isWorking = false; - Engine.loadTerminalContent(); + Engine.loadLocationContent(); } /* Functions for saving and loading the Player data */ diff --git a/src/engine.js b/src/engine.js index cb4ede5d1..89ef3f6e7 100644 --- a/src/engine.js +++ b/src/engine.js @@ -611,6 +611,7 @@ var Engine = { updateDisplays: 4, //Update displays such as Active Scripts display and character display serverGrowth: 450, //Process server growth every minute and a half checkFactionInvitations: 1500, //Check whether you qualify for any faction invitations every 5 minutes + passiveFactionGrowth: 600, }, decrementAllCounters: function(numCycles = 1) { @@ -660,6 +661,12 @@ var Engine = { } Engine.Counters.checkFactionInvitations = 1500; } + + if (Engine.Counters.passiveFactionGrowth <= 0) { + var adjustedCycles = Math.floor((600 - Engine.Counters.passiveFactionGrowth)); + processPassiveFactionRepGain(adjustedCycles); + Engine.Counters.passiveFactionGrowth = 600; + } }, /* Calculates the hack progress for a manual (non-scripted) hack and updates the progress bar/time accordingly */ @@ -895,6 +902,7 @@ var Engine = { var lastUpdate = Player.lastUpdate; var numCyclesOffline = Math.floor((thisUpdate - lastUpdate) / Engine._idleSpeed); + /* Process offline progress */ processServerGrowth(numCyclesOffline); //Should be done before offline production for scripts loadAllRunningScripts(); //This also takes care of offline production for those scripts if (Player.isWorking) { @@ -909,8 +917,11 @@ var Engine = { } } - //Hacknet Nodes + //Hacknet Nodes offline progress processAllHacknetNodeEarnings(numCyclesOffline); + + //Passive faction rep gain offline + processPassiveFactionRepGain(numCyclesOffline); } else { //No save found, start new game console.log("Initializing new game");