-
41 |
- Health: 42 |
- Happiness: 43 |
- Smartness: 44 |
- Appearance: 45 |
- Fitness: 46 | 47 |
├── preview.jpg ├── images ├── job.png ├── prison.png ├── options │ ├── cv.png │ ├── cars.png │ ├── love.png │ ├── health.png │ ├── skills.png │ ├── criminal.png │ ├── education.png │ ├── emigrate.png │ ├── free-time.png │ ├── identity.png │ ├── inventory.png │ ├── sexuality.png │ ├── shopping.png │ ├── drivelicense.png │ ├── real-estate.png │ ├── university.png │ ├── plasticSurgery.png │ └── criminal-record.png ├── relations.png └── shop │ ├── bass.png │ ├── knife.png │ ├── piano.png │ ├── rpg.png │ ├── guitar.png │ ├── handgun.png │ ├── laptop.png │ ├── shotgun.png │ ├── violin.png │ └── smartphone.png ├── README.md ├── js ├── worldEvents.js ├── interface.js ├── events.js ├── items.js ├── main.js ├── characters.js ├── careers.js ├── libs.js ├── countriesData.js └── menu.js ├── index.html └── styles.css /preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/preview.jpg -------------------------------------------------------------------------------- /images/job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/job.png -------------------------------------------------------------------------------- /images/prison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/prison.png -------------------------------------------------------------------------------- /images/options/cv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/cv.png -------------------------------------------------------------------------------- /images/relations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/relations.png -------------------------------------------------------------------------------- /images/shop/bass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/bass.png -------------------------------------------------------------------------------- /images/shop/knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/knife.png -------------------------------------------------------------------------------- /images/shop/piano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/piano.png -------------------------------------------------------------------------------- /images/shop/rpg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/rpg.png -------------------------------------------------------------------------------- /images/options/cars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/cars.png -------------------------------------------------------------------------------- /images/options/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/love.png -------------------------------------------------------------------------------- /images/shop/guitar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/guitar.png -------------------------------------------------------------------------------- /images/shop/handgun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/handgun.png -------------------------------------------------------------------------------- /images/shop/laptop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/laptop.png -------------------------------------------------------------------------------- /images/shop/shotgun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/shotgun.png -------------------------------------------------------------------------------- /images/shop/violin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/violin.png -------------------------------------------------------------------------------- /images/options/health.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/health.png -------------------------------------------------------------------------------- /images/options/skills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/skills.png -------------------------------------------------------------------------------- /images/shop/smartphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/shop/smartphone.png -------------------------------------------------------------------------------- /images/options/criminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/criminal.png -------------------------------------------------------------------------------- /images/options/education.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/education.png -------------------------------------------------------------------------------- /images/options/emigrate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/emigrate.png -------------------------------------------------------------------------------- /images/options/free-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/free-time.png -------------------------------------------------------------------------------- /images/options/identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/identity.png -------------------------------------------------------------------------------- /images/options/inventory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/inventory.png -------------------------------------------------------------------------------- /images/options/sexuality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/sexuality.png -------------------------------------------------------------------------------- /images/options/shopping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/shopping.png -------------------------------------------------------------------------------- /images/options/drivelicense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/drivelicense.png -------------------------------------------------------------------------------- /images/options/real-estate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/real-estate.png -------------------------------------------------------------------------------- /images/options/university.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/university.png -------------------------------------------------------------------------------- /images/options/plasticSurgery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/plasticSurgery.png -------------------------------------------------------------------------------- /images/options/criminal-record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robert1811/life-simulator/HEAD/images/options/criminal-record.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Life simulator 2 | This is a vanillaJS life simulator heavily inspired in games like bitlife, instlife and altlife. You can work, interact with your relatives, get a job and university career, improve your skills, buy stuff and **kill**. 3 | 4 | ## About the project 5 | Its not finished yet, I will be constantly updating this, bringing new content, bug fixes and UI improvements 6 | 7 |  8 | 9 | ## To add 10 | - Military career 11 | - Continue as child after dying 12 | - More shops, jobs, university careers, properties and cars 13 | - Diseases 14 | - More prison actions 15 | - Commercial properties 16 | - More laws 17 | - Taxes 18 | - Writing career 19 | - More social interactions 20 | -------------------------------------------------------------------------------- /js/worldEvents.js: -------------------------------------------------------------------------------- 1 | const worldEvents = {} 2 | 3 | // they display eventually and dont affect any character 4 | 5 | worldEvents.randomWar = () => { 6 | let i = Math.floor(Math.random() * countriesData.length); 7 | let j = Math.floor(Math.random() * countriesData.length); 8 | if(i === j){ 9 | j--; 10 | if(j === -1) j = 2; 11 | }; 12 | 13 | const casusBellis = ['because they have chemical weapons', 'due to their human rights violations', 'they have stolen their land', 'because they want to overthrow their dictatorship', 'in order to restore their democracy']; 14 | const randomCasusBellis = Math.floor(Math.random() * casusBellis.length); 15 | 16 | return `${countriesData[i].country} has declared war on ${countriesData[j].country} ${casusBellis[randomCasusBellis]}` 17 | 18 | } 19 | 20 | worldEvents.randomAsteroid = () =>{ 21 | let i = Math.floor(Math.random() * countriesData.length); 22 | let casualties = Math.floor(Math.random() * 5000); 23 | 24 | return `An asteroid crashed in ${countriesData[i].country}, ${casualties} people died`; 25 | } 26 | 27 | worldEvents.randomTerroristAttack = () => { 28 | let i = Math.floor(Math.random() * countriesData.length); 29 | let casualties = Math.floor(Math.random() * 120); 30 | let injuried = Math.floor(Math.random() * 150) 31 | 32 | return `Terrorist attack in ${countriesData[i].country}, ${casualties} deaths and ${injuried} injuried` 33 | } 34 | 35 | const worldEventsMethodArr = Object.entries(worldEvents); 36 | const worldEventsAmount = worldEventsMethodArr.length; 37 | 38 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |${player.fullName} was born in ${player.birthplace} at year ${year - player.age}. ${pronoun} was son of ${dadName} and ${momName}${siblingLength !== 0 ? `, ${player.gender === 'male' ? 'brother' : 'sister'} of ${siblingLength} ${siblingLength > 1 ? 'persons' : 'person'}.` : '.'}
${pronoun} never got a job.
${pronoun} left this world with ${moneyFormat(player.money.total)} $ on his bank account. ${player.inventory.houses.length !== 0 ? `${pronoun} had ${player.inventory.houses.length} properties.` : `${pronoun} was homeless.`}
${pronoun} passed away at age of ${player.age} ${player.deathCause} in ${player.location}
103 | ` 104 | 105 | document.getElementById('death-screen').style.display = 'block' 106 | } 107 | 108 | const annualChanges = () => { 109 | year++; 110 | for (let person of characters) { 111 | if (person.alive) person.age++; 112 | pregnancyHandler(person) 113 | } 114 | 115 | textContainer.innerHTML += ` 116 |${year} - ${player.age} years old
117 | ` 118 | 119 | //death possibility 120 | for (let person of characters) { 121 | randomDeath(person) 122 | } 123 | 124 | // shows if player is in the stage of childhood, adulthood or elderhood 125 | lifeStageDisplayer() 126 | 127 | //this is for events such as first words and university 128 | specificEvents() 129 | 130 | //random messages 131 | if (Math.floor(Math.random() * 10) === 5) 132 | textContainer.innerHTML += `${worldEventsMethodArr[Math.floor(Math.random() * worldEventsAmount)][1]()}
` 133 | 134 | player.money.total += player.money.income - player.money.expenses 135 | 136 | // job related stats 137 | if (player.job !== 'none') { 138 | const random = Math.round(Math.random()) 139 | if (random === 0) 140 | player.job.performance += Math.floor(Math.random() * 5) 141 | else 142 | player.job.performance -= Math.floor(Math.random() * 5) 143 | } 144 | 145 | // for university 146 | studyingProcess(textContainer) 147 | if(player.job != 'none') player.job.buff(player) 148 | if(player.currentCareer.studying) player.currentCareer.buff(player); 149 | statsChanges() 150 | statsBuffer() 151 | statsLimit(player) 152 | handleStatBars(player, true); 153 | skillLeveler() 154 | 155 | //scroll handling 156 | scrolldown(textContainer) 157 | 158 | //displaying flow of money 159 | moneyViewer() 160 | 161 | resetAvaibleActions() 162 | 163 | randomizeHouseStats() 164 | prisonHandler(player) 165 | eventsHandler() 166 | } 167 | 168 | const closeMenu = document.getElementById('close-menu'); 169 | closeMenu.addEventListener('click', e => { 170 | menuTemplate.style.display = 'none' 171 | }) -------------------------------------------------------------------------------- /js/events.js: -------------------------------------------------------------------------------- 1 | //random events 2 | const childhoodEvents = [ 3 | { 4 | display() { 5 | createStoryEvent({ 6 | title: 'Happy Birthday!', 7 | body(id) { 8 | return ` 9 |What are you going to do?
10 |I celebrated my birthday
23 |I invited my ${guests}
24 | ` 25 | scrolldown(textContainer) 26 | } 27 | }, 28 | { 29 | display() { 30 | const person = new Person(undefined, undefined, player.age, player.gender == 'male' ? 'female' : 'male') 31 | const appearance = person.stats.appearance 32 | const { fullName, gender, age } = person 33 | const pronoun = gender === 'male' ? 'him' : 'her' 34 | createStoryEvent({ 35 | title: 'Kiss', 36 | body(id) { 37 | return ` 38 |Name: ${fullName}
39 |Gender: ${gender}
40 |Age: ${age}
41 |Appearance:
42 | 45 |You got the oportunity to kiss ${pronoun}. Would you like to do it?
47 |You kissed ${pronoun}.
62 |${pronoun == 'him' ? 'His' : 'Her'} enjoyment.
63 | 66 |Someone asked you for the direction of ${place}.
86 |I got insulted by inmates
' 107 | 108 | createStoryEvent({ 109 | title: `The inmates called you ${insult}`, 110 | body(id) { 111 | return ` 112 |I insulted them
` 120 | scrolldown(textContainer) 121 | 122 | closeStoryEvent(id) 123 | } 124 | } 125 | ] 126 | 127 | const jobEvents = [ 128 | { 129 | display() { 130 | textContainer.innerHTML += ` 131 |We have a job meeting
132 | ` 133 | scrolldown(textContainer) 134 | createStoryEvent({ 135 | title: 'Job Meeting', 136 | body(id) { 137 | return ` 138 |You have a meeting in your job, what are you going to do?
139 |I said nothing in that meeting
147 | ` 148 | closeStoryEvent(id) 149 | scrolldown(textContainer) 150 | }, 151 | proposeIdea(id) { 152 | const smartness = player.stats.smartness; 153 | const random = Math.floor(Math.random() * 50) + 50 154 | 155 | if (random <= smartness) { 156 | textContainer.innerHTML += ` 157 |They congratulated me
158 | ` 159 | closeStoryEvent(id) 160 | } else 161 | textContainer.innerHTML += ` 162 |They told me to shut up
163 | ` 164 | closeStoryEvent(id) 165 | scrolldown(textContainer) 166 | } 167 | } 168 | ] 169 | 170 | const obligatoryEvents = { 171 | firstWords: { 172 | display() { 173 | createStoryEvent({ 174 | title: 'Your first words', 175 | body(id) { 176 | return ` 177 |My first words were "${words}"
189 | ` 190 | } 191 | } 192 | } 193 | 194 | const eventsHandler = () => { 195 | if (!player.alive || player.age < 4) return 196 | 197 | const displayHandler = (events, probability) => { 198 | const random = Math.floor(Math.random() * 100) 199 | const eventIndex = Math.floor(Math.random() * events.length) 200 | if (random + 5 <= probability) { 201 | events[eventIndex].display() 202 | } 203 | } 204 | 205 | if (player.prison.jailed) return displayHandler(prisonEvents, 10) 206 | 207 | if (player.job != 'none') displayHandler(jobEvents, 8) 208 | 209 | if (player.lifeStage === 'childhood') displayHandler(childhoodEvents, 20) 210 | 211 | else if (player.lifeStage === 'adulthood') displayHandler(adulthoodEvents, 8) 212 | } -------------------------------------------------------------------------------- /js/items.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const items = { 4 | weapons: [ 5 | { 6 | label: 'Knife', 7 | price: 5000, 8 | successChance: 35, 9 | image: 'knife.png', 10 | type: 'weapons', 11 | index: 0 12 | }, 13 | { 14 | label: 'Handgun', 15 | price: 32000, 16 | successChance: 55, 17 | image: 'handgun.png', 18 | type: 'weapons', 19 | index: 1 20 | }, 21 | { 22 | label: 'Shotgun', 23 | price: 50000, 24 | successChance: 75, 25 | image: 'shotgun.png', 26 | type: 'weapons', 27 | index: 2 28 | }, 29 | { 30 | label: 'RPG', 31 | price: 150000, 32 | successChance: 86, 33 | image: 'rpg.png', 34 | type: 'weapons', 35 | index: 3 36 | } 37 | ], 38 | instruments: [ 39 | { 40 | label: 'Piano', 41 | price: 16000, 42 | image: 'piano.png', 43 | type: 'instruments', 44 | index: 0 45 | }, 46 | { 47 | label: 'Guitar', 48 | price: 5000, 49 | image: 'guitar.png', 50 | type: 'instruments', 51 | index: 1 52 | }, 53 | { 54 | label: 'Violin', 55 | price: 5000, 56 | image: 'violin.png', 57 | type: 'instruments', 58 | index: 2 59 | }, 60 | { 61 | label: 'Bass', 62 | price: 4800, 63 | image: 'bass.png', 64 | type: 'instruments', 65 | index: 3 66 | }, 67 | { 68 | label: 'Flute', 69 | price: 5, 70 | image: 'flute.png', 71 | type: 'instruments', 72 | index: 4 73 | } 74 | ], 75 | electronics : [ 76 | { 77 | label: 'Smartphone', 78 | price: 6000, 79 | image: 'smartphone.png', 80 | type: 'electronics', 81 | index: 0 82 | }, 83 | { 84 | label: 'Laptop', 85 | price: 12000, 86 | image: 'laptop.png', 87 | type: 'electronics', 88 | index: 1 89 | } 90 | ], 91 | fastFood: [ 92 | { 93 | label: 'Hamburguer', 94 | price: 35, 95 | image: 'hamburguer.png', 96 | type: 'fastFood', 97 | index: 0, 98 | statChanges: { 99 | health: -1, 100 | happiness: 5, 101 | fitness: -1 102 | } 103 | }, 104 | { 105 | label: 'Pizza', 106 | price: 50, 107 | image: 'pizza.png', 108 | type: 'fastFood', 109 | index: 1, 110 | statChanges: { 111 | health: -1, 112 | happiness: 7, 113 | fitness: -1 114 | } 115 | }, 116 | { 117 | label: 'Hot dogs', 118 | price: 30, 119 | image:'hot_dog.png', 120 | type: 'fastFood', 121 | index: 2, 122 | statChanges: { 123 | health: -1, 124 | happiness: 3, 125 | fitness: -1 126 | } 127 | } 128 | ], 129 | vegetables: [ 130 | { 131 | label: 'Potato', 132 | price: 10, 133 | image: 'potato.png', 134 | type: 'vegetables', 135 | index: 0, 136 | statChanges: { 137 | health: 2 138 | } 139 | }, 140 | { 141 | label: 'Carrot', 142 | price: 50, 143 | image: 'carrot.png', 144 | type: 'vegetables', 145 | index: 1, 146 | statChanges: { 147 | health: 5 148 | } 149 | }, 150 | { 151 | label: 'Broccoli', 152 | price: 80, 153 | image: 'broccoli.png', 154 | type: 'vegetables', 155 | index: 2, 156 | statChanges: { 157 | health: 7 158 | } 159 | } 160 | ], 161 | desserts: [ 162 | { 163 | label: 'Cotton candy', 164 | price: 15, 165 | image: 'cotton_candy.png', 166 | index: 0, 167 | type: 'desserts', 168 | statChanges: { 169 | happiness: 3, 170 | health: -1 171 | } 172 | }, 173 | { 174 | label: 'Ice cream', 175 | price: 15, 176 | image: 'ice_cream.png', 177 | index: 1, 178 | type: 'desserts', 179 | statChanges: { 180 | happiness: 5 181 | } 182 | }, 183 | { 184 | label: 'Chocolate bar', 185 | price: 15, 186 | image: 'chocolate.png', 187 | index: 2, 188 | type: 'desserts', 189 | statChanges: { 190 | happiness: 4, 191 | fitness: -1 192 | } 193 | } 194 | ], 195 | alcoholic: [ 196 | { 197 | label: 'Wine', 198 | price: 60, 199 | image: 'wine.png', 200 | index: 0, 201 | type: 'alcoholic', 202 | statChanges: { 203 | happiness: 12, 204 | health: -8 205 | } 206 | }, 207 | { 208 | label: 'Beer', 209 | price: 25, 210 | image: 'beer.png', 211 | index: 1, 212 | type: 'alcoholic', 213 | statChanges: { 214 | happiness: 10, 215 | health: -8 216 | } 217 | }, 218 | { 219 | label: 'Vodka', 220 | price: 50, 221 | image: 'vodka.png', 222 | index: 2, 223 | type: 'alcoholic', 224 | statChanges: { 225 | happiness: 11, 226 | health: -7 227 | } 228 | } 229 | ], 230 | nonAlcoholic: [ 231 | { 232 | label: 'Orange juice', 233 | price: 15, 234 | image: 'orange_juice.png', 235 | index: 0, 236 | type: 'nonAlcoholic', 237 | statChanges: { 238 | happiness: 4 239 | } 240 | }, 241 | { 242 | label: 'Milk', 243 | price: 5, 244 | image: 'milk.png', 245 | index: 1, 246 | type: 'nonAlcoholic', 247 | statChanges: { 248 | happiness: 2 249 | } 250 | } 251 | ] 252 | } 253 | 254 | const assets = { 255 | houses: [ 256 | { 257 | label: 'Modern House', 258 | age: Math.floor(Math.random() * 10), 259 | condition: Math.floor(Math.random() * 100), 260 | price: 510000 261 | }, 262 | { 263 | label: 'House boat', 264 | age: Math.floor(Math.random() * 120), 265 | condition: Math.floor(Math.random() * 100), 266 | price: 60000 267 | }, 268 | { 269 | label: 'Tiny apartment', 270 | age: Math.floor(Math.random() * 100), 271 | condition: Math.floor(Math.random() * 100), 272 | price: 75000 273 | }, 274 | { 275 | label: 'Big Mansion', 276 | age: Math.floor(Math.random() * 100), 277 | condition: Math.floor(Math.random() * 100), 278 | price: 2000000 279 | } 280 | ], 281 | cars: [ 282 | { 283 | label: 'Alpine A110', 284 | price: 107000, 285 | }, { 286 | label: 'Aiways U5', 287 | price: 42690 288 | }, { 289 | label: 'Bolt 550S', 290 | price: 124000 291 | }, { 292 | label: 'Onyx Zeal', 293 | price: 113000 294 | }, { 295 | label: 'FRX Catalyst', 296 | price: 58000 297 | }, { 298 | label: 'Shelly Behemot GT', 299 | price: 56000 300 | }, { 301 | label: 'EOS Nimbus', 302 | price: 54000 303 | }, { 304 | label: 'Ranger Expedition', 305 | price: 26000 306 | }, { 307 | label: 'Ranger Radiance', 308 | price: 35000 309 | } 310 | ] 311 | } 312 | 313 | const randomizeHouseStats = () => { 314 | for(let house of assets.houses){ 315 | house.age = Math.floor(Math.floor(Math.random() * 120)); 316 | house.condition = Math.floor(Math.floor(Math.random() * 100)); 317 | } 318 | // for(let car of assets.cars){ 319 | // console.log(car) 320 | // } 321 | } 322 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let characters = []; 4 | 5 | class Person { 6 | constructor(name, surname, age, gender, nationality, money, location) { 7 | this.gender = gender || genderRandomizer() 8 | this.nationality = nationality || countryRandomizer(); 9 | this.language = languageQuery(this.nationality) 10 | this.name = name || nameRandomizer(this.language, this.gender); 11 | this.surname = surname || surnameRandomizer(this.language); 12 | this.age = age || 0; 13 | this.money.total = money ? money : 0; 14 | this.location = location || birthplaceQuery(this.nationality) 15 | this.birthplace = this.location 16 | this.driverLicense = this.age > 18 ? true : false; 17 | } 18 | 19 | inventory = { weapons: [], instruments: [], electronics: [], houses: [], cars: []}; 20 | 21 | sexuality = 'heterosexual' 22 | 23 | stats = { 24 | health: randomStat(70, 30), 25 | happiness: randomStat(0, 100), 26 | smartness: randomStat(0, 100), 27 | fitness: randomStat(0, 35), 28 | appearance: randomStat(0, 100) 29 | } 30 | 31 | relationships = { 32 | parents: [], 33 | siblings: [], 34 | partner: [], 35 | friends: [], 36 | offspring: [] 37 | } 38 | alive = true; 39 | career = {}; 40 | currentCareer = {studying: false} 41 | 42 | skills = { 43 | programming: { 44 | level: 0, 45 | xp: 0, 46 | xpNeeded: 50, 47 | }, 48 | handiness: { 49 | level: 0, 50 | xp: 0, 51 | xpNeeded: 50, 52 | }, 53 | writing: { 54 | level: 0, 55 | xp: 0, 56 | xpNeeded: 50, 57 | }, 58 | art: { 59 | level: 0, 60 | xp: 0, 61 | xpNeeded: 50, 62 | }, 63 | music: { 64 | level: 0, 65 | xp: 0, 66 | xpNeeded: 50 67 | } 68 | } 69 | 70 | //activities which you pay for increasing skills and stats 71 | freetime = { 72 | isReading: false, 73 | isTakingMusicLessons: false, 74 | isAttendingParties: false, 75 | goesToGym: false 76 | } 77 | 78 | job = 'none'; 79 | 80 | //in cv goes your employment history 81 | cv = []; 82 | 83 | money = { 84 | expenses: 0, 85 | income: 0, 86 | total: 0 87 | } 88 | 89 | get fullName() { 90 | return `${this.name} ${this.surname}` 91 | } 92 | 93 | //this is used when you want to access to certain character by using this index with the characters array 94 | characterIndex = characters.length 95 | 96 | criminalRecord = { 97 | yearsInPrison: 0, 98 | murderAttempts: 0, 99 | murder: 0, 100 | prisonEscapes: 0 101 | } 102 | 103 | prison = { 104 | yearsLeft: 0, 105 | sentenceTime: 0, 106 | jailed: false 107 | } 108 | 109 | // this limits your actions per year 110 | actions = { 111 | programming: 0, 112 | writing: 0, 113 | workHarder: 0, 114 | music: 0, 115 | meanActions: 0, 116 | friendlyActions: 0, 117 | romanticActions: 0, 118 | askPromotion: 0 119 | } 120 | 121 | socialMedia = { 122 | youtube: { 123 | created: false, 124 | created_at: null, 125 | username: null, 126 | videos: [], 127 | subscribers: 0 128 | }, 129 | instagram: { 130 | created: false, 131 | created_at: null, 132 | username: null, 133 | posts: [], 134 | followers: 0 135 | } 136 | } 137 | } 138 | 139 | const createFamily = (player) => { 140 | const parentsAge = () => { 141 | let age = Math.floor(Math.random() * 40) + player.age; 142 | if (age - player.age < 18) age = age + 18 + player.age; 143 | return age; 144 | } 145 | 146 | 147 | let dad = new Person(undefined, player.surname, parentsAge(), 'male', player.nationality); 148 | dad.stats.relationWithPlayer = Math.floor(Math.random() * 100); 149 | characters.push(dad); 150 | 151 | let mom = new Person(undefined, undefined, dad.age + Math.floor(Math.random() * 10), 'female', player.nationality); 152 | mom.stats.relationWithPlayer = Math.floor(Math.random() * 100); 153 | characters.push(mom) 154 | 155 | dad.relationships.partner.push(mom); 156 | mom.relationships.partner.push(dad); 157 | 158 | player.relationships.parents.push(dad); 159 | player.relationships.parents.push(mom) 160 | 161 | let siblingsAmount = Math.floor(Math.random() * 3); 162 | 163 | while (siblingsAmount > 0) { 164 | let randomAge = Math.floor(Math.random() * 5); 165 | let sibling = new Person(undefined, player.surname, randomAge, undefined, player.nationality); 166 | sibling.stats.relationWithPlayer = Math.floor(Math.random() * 100); 167 | characters.push(sibling); 168 | player.relationships.siblings.push(sibling); 169 | siblingsAmount--; 170 | } 171 | } 172 | 173 | const firstMessage = () => { 174 | textContainer.innerHTML = ` 175 |${year} - ${player.age === 0 ? 'birth' : `${player.age} years old`}
176 |My name is ${player.fullName}
177 |I was born ${player.gender} in ${player.location} on year ${year}
178 |My father is ${player.relationships.parents[0].fullName}, he works as a ${player.relationships.parents[0].job.label.toLowerCase()}
179 |My mother is ${player.relationships.parents[1].fullName}, she works as a ${player.relationships.parents[1].job.label.toLowerCase()}
180 | ` 181 | } 182 | 183 | let player; 184 | 185 | const interfaceLoading = () => { 186 | handleStatBars(player, true); 187 | lifeStageDisplayer() 188 | moneyViewer() 189 | jobAssigner(characters) 190 | firstMessage() 191 | const menu = document.getElementById('create-character-screen') 192 | menu.style.display = 'none' 193 | menu.innerHTML = ` 194 |I finished my career
` 22 | } 23 | } 24 | 25 | const statsLimit = (person) => { 26 | let stats = person.stats; 27 | for(let stat of Object.entries(stats)){ 28 | if(stat[1] < 0) person.stats[stat[0]] = 0 29 | else if (stat[1] > 100) person.stats[stat[0]] = 100 30 | } 31 | if(person.job !== 'none') 32 | if(person.job.performance > 100) 33 | person.job.performance = 100 34 | else if (person.job.performance < 0) 35 | person.job.performance = 0 36 | 37 | } 38 | 39 | const statsBuffer = () => { 40 | if(player.freetime.isReading){ 41 | if(player.money.total > 0){ 42 | player.stats.smartness += 3; 43 | } 44 | else { 45 | player.freetime.isReading = false 46 | player.money.expenses -= 200 47 | } 48 | 49 | } 50 | if(player.freetime.isAttendingParties){ 51 | if(player.money.total > 0) player.stats.happiness += 5 52 | else { 53 | player.freetime.isAttendingParties = false 54 | player.money.expenses -= 500 55 | } 56 | } 57 | if(player.freetime.isTakingMusicLessons){ 58 | if(player.money.total > 0) player.skills.music.xp += 25; 59 | else { 60 | player.freetime.isTakingMusicLessons = false 61 | player.money.expenses -= 2000 62 | } 63 | } 64 | if(player.freetime.goesToGym){ 65 | if(player.money.total > 0) { 66 | player.stats.health++; 67 | player.stats.fitness += 6; 68 | } else { 69 | player.freetime.goesToGym = false 70 | player.money.expenses -= 1800 71 | } 72 | } else player.stats.fitness--; 73 | 74 | 75 | } 76 | 77 | const specificEvents = () => { 78 | switch (player.age) { 79 | case 1: 80 | obligatoryEvents.firstWords.display() 81 | break; 82 | case 3: 83 | player.currentEducation = 'preschool' 84 | textContainer.innerHTML += `I started prescholar
` 85 | break; 86 | 87 | case 6: 88 | player.currentEducation = 'elementary' 89 | textContainer.innerHTML += `I started elementary school
` 90 | break; 91 | 92 | case 12: 93 | player.currentEducation = 'highschool' 94 | textContainer.innerHTML += `I started highschool
` 95 | break; 96 | 97 | case 18: 98 | player.career['education'] = {name: 'Highschool'} 99 | windows.university.display() 100 | } 101 | } 102 | 103 | const careerPreviewer = () => { 104 | let string = ''; 105 | let object = {education: 'No degrees yet
'} 106 | for(let obj of Object.entries(player.career)){ 107 | if(obj[0] !== 'education'){ 108 | string = string.concat(`${person.fullName} ${reason} at age of ${person.age}
` 168 | 169 | person.deathCause = reason; 170 | 171 | if(person.job !== 'none'){ 172 | person.job.until = year; 173 | person.cv.push(person.job) 174 | person.job = 'none' 175 | } 176 | 177 | if(person.characterIndex === player.characterIndex){ 178 | const ageBtnContainer = document.getElementById('age-btn-container'); 179 | ageBtnContainer.innerHTML = ` 180 | 181 | ` 182 | } 183 | } 184 | 185 | const prisonHandler = (person) => { 186 | if(!person.prison.jailed) return 187 | 188 | person.prison.yearsLeft--; 189 | person.criminalRecord.yearsInPrison++; 190 | 191 | if(person.prison.yearsLeft === 0){ 192 | person.prison.jailed = false 193 | person.prison.sentenceTime = 0; 194 | leftBtnContainer.innerHTML = '' 195 | textContainer.innerHTML += `I got out of prison
` 196 | } 197 | } 198 | 199 | const jobPerformanceHandler = () => { 200 | if(player.job === 'none') return 201 | 202 | const performance = player.job.performance 203 | const random = Math.round(Math.random() * 10) 204 | if(performance <= 10 && random === 2){ 205 | player.job.until = year 206 | player.cv.push(player.job) 207 | player.job = 'none' 208 | } else if(performance >= 75 && random === 5){ 209 | 210 | } 211 | } 212 | 213 | const resetAvaibleActions = () => { 214 | for(let action of Object.entries(player.actions)){ 215 | player.actions[action[0]] = 0 216 | } 217 | } 218 | 219 | const arrest = (min, max, person) => { 220 | person.prison.sentenceTime = min + Math.floor(Math.random() * max) 221 | person.prison.yearsLeft = person.prison.sentenceTime 222 | person.prison.jailed = true; 223 | 224 | leftBtnContainer.innerHTML = ` 225 | 228 |Prison
229 | ` 230 | if(player.job !== 'none') { 231 | player.job === 'none'; 232 | textContainer.innerHTML += `I lost my job
` 233 | } 234 | } 235 | 236 | const arrestByMurder = (person) => { 237 | arrest(8, 17, person) 238 | } 239 | 240 | const arrestByStealingCar = (person) => { 241 | arrest(1, 3, person) 242 | } 243 | 244 | const pregnancyHandler = (person) => { 245 | if(!person.pregnant) return 246 | 247 | person.pregnant = false; 248 | const partner = person.relationships.partner[0] 249 | const possibleGenders = ['male', 'female'] 250 | const gender = possibleGenders[Math.round(Math.random())] 251 | 252 | if(person.characterIndex == player.characterIndex || person.characterIndex == player.characterIndex.relationships.partner[0]){ 253 | const pronoun = gender === 'male' ? 'him' : 'her' 254 | modalBackground.style.display = 'flex' 255 | eventTitle.innerText = `Its a ${gender == 'male' ? 'boy' : 'girl'}` 256 | eventBody.innerHTML = ` 257 |How will you call ${pronoun}
258 | 259 |Level: ${skill[1].level}
183 |You do not have job history
` 213 | 214 | let string = ''; 215 | for(let job of player.cv){ 216 | string = string.concat(` 217 |My ${gender === 'male' ? 'son' : 'daughter'} has born. ${gender === 'male' ? 'His' : 'Her'} name is ${offspring.name}
335 | ` 336 | closeEvent(); 337 | } 338 | 339 | const randomNameForChildren = (personIndex) => { 340 | const person = characters[personIndex] 341 | const gender = person.gender; 342 | const array = names[person.language][gender] 343 | const random = Math.floor(Math.random() * array.length) 344 | document.getElementById('name-field').value = array[random] 345 | } 346 | 347 | const closeEvent = () => { 348 | eventTitle.innerText = ''; 349 | eventBody.innerHTML = ''; 350 | eventContainer.style.display = 'none' 351 | modalBackground.style.display = 'none'; 352 | } 353 | 354 | const showEvent = ({title, body}) => { 355 | eventTitle.innerText = title 356 | eventBody.innerHTML = body 357 | eventContainer.style.display = 'block' 358 | modalBackground.style.display = 'flex' 359 | } 360 | 361 | // used for story events 362 | const createStoryEvent = ({title, body}) => { 363 | const eventsContainer = document.getElementById("events-container") 364 | const index = eventsContainer.children.length 365 | eventsContainer.innerHTML += ` 366 |
Free time
18 |
Cars
21 |
Real Estate
24 |
Shopping
27 |
Emigrate
30 |
Driver license
33 |
Love
36 |
Plastic surgeries
39 |
University
43 |
Criminal
46 | +3 smartness
81 |200$
88 |+25 music
95 |2000$
102 |+5 happiness
109 |500$
116 |+3 fitness
123 |1800$
130 |
Identity
374 |
Skills
377 |
Inventory
380 |
Education
383 |
Curriculum Vitae
386 |
Sexuality
389 |
Health
392 |
Criminal record
395 | No items owned yet
436 |Are you sure you want to do this
458 |You found a ${car.label}, would you steal it?
480 |You stole this car succesfully
502 |I stole a ${carName.toLowerCase()}
` 505 | } else { 506 | eventBody.innerHTML = ` 507 |You got arrested
508 |I tried to steal a ${carName.toLowerCase()}
` 512 | textContainer.innerHTML += `I got arrested for ${player.prison.sentenceTime} years
` 513 | } 514 | }, 515 | }, 516 | murder: { 517 | display() { 518 | const events = [{ 519 | message: 'A beggar asked for your charity', 520 | target: 'beggar', 521 | gender: 'male' 522 | }, { 523 | message: 'A prostitute offers you her services', 524 | target: 'prostitute', 525 | gender: 'female' 526 | }] 527 | const random = Math.floor(Math.random() * events.length) 528 | const pronoun = events[random].gender === "male" ? 'him' : 'her' 529 | const victim = events[random].target 530 | 531 | showEvent({ 532 | title: 'Murder', 533 | body: ` 534 |${events[random].message}
535 |I killed a ${victim}
561 | ` 562 | const probabilityOfArrest = Math.floor(Math.random() * 100) 563 | if (probabilityOfArrest > 60) { 564 | eventBody.innerHTML = ` 565 |You got caught by the police, you are arrested
566 |The police caught me
571 |I have been arrested for ${player.prison.sentenceTime} years
572 | ` 573 | } else { 574 | eventBody.innerHTML = ` 575 |You killed the ${victim} succesfully
576 |Your murder attempt failed, you got denounced
585 |My murder attempt failed
589 |I got denounced
590 |I have been arrested for ${player.prison.sentenceTime} years
591 | ` 592 | } 593 | }, 594 | }, 595 | robbery() { 596 | showEvent({ 597 | title: 'Robbery', 598 | body: ` 599 |Fix your insecurities today
612 |You cant afford this
640 |+${buff} appearance
647 |I paid for a ${operation}
652 | ` 653 | handleStatBars(player, true) 654 | }, 655 | options(price, operation) { 656 | return ` 657 |Price: ${moneyFormat(price)} $
658 |Total money: ${moneyFormat(player.money.total)} $
699 |Income: ${moneyFormat(player.money.income)} $
700 |Expenses: ${moneyFormat(player.money.expenses)} $
701 |Balance: ${moneyFormat(player.money.income - player.money.expenses)} $
702 |Full name: ${player.fullName}
711 |Gender: ${player.gender}
712 |Age: ${player.age}
713 |Nationality: ${player.nationality}
714 |Location: ${player.location}
715 |Sexuality: ${player.sexuality}
716 |${careerPreviewer().education}
726 |Years arrested: ${yearsInPrison === 0 ? 'none' : yearsInPrison + ' years'}
759 |Murder attempts: ${murderAttempts === 0 ? 'none' : murderAttempts}
760 |Murder: ${murder === 0 ? 'none' : murder}
761 |Prison escapes: ${prisonEscapes === 0 ? 'none' : prisonEscapes}
762 |Price: ${moneyFormat(price)} $
801 |I sold an item for ${moneyFormat(price)}$
` 812 | 813 | player.inventory[type].splice(parseInt(index), 1) 814 | 815 | let i = 0 816 | for (let item of player.inventory[type]) { 817 | item.inventoryIndex = i; 818 | i++ 819 | } 820 | 821 | player.money.total += parseInt(price) 822 | moneyViewer() 823 | }, 824 | useItem(data) { 825 | const type = data.getAttribute('data-type') 826 | const index = data.getAttribute('data-index') 827 | const object = player.inventory[type][index] 828 | 829 | if (type === 'weapons') { 830 | showEvent({ 831 | title: object.label, 832 | body: ` 833 |${object.successChance}% efficiency
835 |I bought a ${newObj.label}
`; 919 | closeEvent() 920 | document.getElementById(`${property}-${index}`).remove() 921 | moneyViewer() 922 | 923 | } else { 924 | eventTitle.innerText = 'Cant afford this' 925 | eventBody.innerHTML = `You ${kind === 'food' ? 'ate' : 'drank'} a ${item.label.toLowerCase()}
940 |+25 music skill earned!
951 |You have commited murder succesfully
998 |I killed ${name}
1002 | ` 1003 | } else { 1004 | eventBody.innerHTML = ` 1005 |Your assasination attemp failed! you got arrested
1007 |My assasination attempt failed, I got denounced
1016 |I have been arrested for ${player.prison.sentenceTime} years 1017 |
1018 | ` 1019 | 1020 | } 1021 | }, 1022 | }, 1023 | computer: { 1024 | practiceWriting() { 1025 | player.actions.writing++ 1026 | player.skills.writing.xp += 25; 1027 | eventBody.innerHTML = ` 1028 |+25 writing skill earned!
1029 |I practiced writing
1033 | ` 1034 | skillLeveler() 1035 | }, 1036 | practiceProgramming() { 1037 | player.actions.programming++ 1038 | player.skills.programming.xp += 25; 1039 | eventBody.innerHTML = ` 1040 |+25 programming skill earned!
1041 |I practiced programming
1045 | ` 1046 | skillLeveler() 1047 | }, 1048 | playVideogames() { 1049 | const videogames = ['Among sus', 'Minekampf', 'Call of Honor', 'The Binding of Ray', 'Hollow Warrior', 'Raymonds Mod', 'Hearts of Steel IV', 'Asia Universallis IV', 'Fall-in: New Ohio'] 1050 | player.stats.happiness += 5; 1051 | 1052 | const gamePlayed = videogames[Math.floor(Math.random() * videogames.length)] 1053 | 1054 | eventBody.innerHTML = ` 1055 |You played ${gamePlayed}
1056 |+5 happiness
1057 |I played ${gamePlayed}
` 1060 | } 1061 | }, 1062 | smartphone: { 1063 | watchVideo() { 1064 | const location = countryQuery(player.location) 1065 | if (location.laws.banned_youtube) { 1066 | return eventBody.innerHTML = ` 1067 |Youtube is not available in your country
1068 |I watched a video of ${randomUser}
1079 | ` 1080 | player.stats.happiness += Math.round(Math.random() * 10) 1081 | handleStatBars(player, true) 1082 | }, 1083 | }, 1084 | ownedAssetWindow(data) { 1085 | const type = data.getAttribute('data-type') 1086 | const index = data.getAttribute('data-index'); 1087 | const asset = player.inventory[type][index] 1088 | const canThrowParty = asset.location === player.location ? true : false 1089 | 1090 | modalBackground.style.display = 'flex' 1091 | eventTitle.innerText = asset.label 1092 | if (type === 'houses') 1093 | eventBody.innerHTML = ` 1094 |Age: ${asset.age}
1095 |Value: ${moneyFormat(asset.price)} $
1096 |Condition: ${asset.condition}
1097 |Location: ${asset.location}
1098 |Value: ${moneyFormat(asset.price)}
1108 | ${player.driverLicense ? ` 1109 |I created a ${socialMedia} account called ${username}
1125 | ` 1126 | closeEvent() 1127 | menuTemplate.style.display = 'none' 1128 | }, 1129 | display() { 1130 | const laws = countryQuery(player.location).laws 1131 | 1132 | eventTitle.innerText = 'Social media' 1133 | eventBody.innerHTML = ` 1134 |Username: ${stats.username}
1152 |Subscribers: ${stats.subscribers}
1153 |Creation year: ${stats.created_at}
1154 |Thematic:
1165 | 1171 |Title:
1172 | 1173 |Views: ${views}
1199 |Likes: ${likes}
1200 |New subscribers: ${newSubs}
1201 |ID: ${video.id}
1215 |Thematic: ${video.thematic}
1216 |Views: ${video.views}
1217 |Likes: ${video.likes}
1218 |Youtube is banned in your country
1240 |Username: ${stats.username}
1254 |Followers: ${stats.followers}
1255 |Creation year: ${stats.created_at}
1256 |Title
1266 | 1267 |${post.description}
1292 |ID: ${post.id}
1293 |${post.likes} likes
1294 | `)) 1295 | if (str === '') str = 'Relationship: ${relationship}
1326 |Age: ${person.age}
1327 | ${person.age >= 16 ? ` 1328 |Occupation: ${person.job !== 'none' ? person.job.label : 'unemployed'}
1329 | ${person.job !== 'none' ? `Salary: ${moneyFormat(person.job.salary)} $
` : ''} 1330 | ` : ''} 1331 |Location: ${person.location}
1332 |Nationality: ${person.nationality}
1333 |We spent time together
1414 |+8 relationship
1415 |I spent time with ${person.fullName}
` 1419 | } 1420 | }, 1421 | mean: { 1422 | yell(data) { 1423 | if (player.actions.meanActions >= 3) return 1424 | 1425 | player.actions.meanActions++ 1426 | const index = data.getAttribute('data-index'); 1427 | let person = characters[index] 1428 | const isPartner = person.relationships.partner[0].characterIndex === player.characterIndex ? true : false; 1429 | 1430 | person.stats.relationWithPlayer -= 10 1431 | 1432 | if (isPartner) 1433 | person.stats.loveToPartner -= 20 1434 | statsLimit(person) 1435 | 1436 | eventBody.innerHTML = ` 1437 |You yelled at ${person.gender === 'male' ? 'him' : 'her'}
1438 |-10 relationship
1439 | ${isPartner ? '-20 love
' : ''} 1440 |You yelled at ${person.fullName}
` 1443 | 1444 | 1445 | menu.relationships() 1446 | }, 1447 | insult(data) { 1448 | if (player.actions.meanActions >= 3) return 1449 | 1450 | player.actions.meanActions++ 1451 | const index = data.getAttribute('data-index'); 1452 | let person = characters[index] 1453 | const isPartner = person.relationships.partner[0].characterIndex === player.characterIndex ? true : false; 1454 | 1455 | person.stats.relationWithPlayer -= 8 1456 | 1457 | if (isPartner) 1458 | person.stats.loveToPartner -= 30 1459 | 1460 | eventBody.innerHTML = ` 1461 |You insulted ${person.gender === 'male' ? 'him' : 'her'}
1462 |-8 relationship
1463 | ${isPartner ? '-30 love
' : ''} 1464 |You insulted ${person.fullName}
` 1467 | statsLimit(person) 1468 | 1469 | menu.relationships() 1470 | }, 1471 | assault(data) { 1472 | if (player.actions.meanActions >= 3) return 1473 | 1474 | const index = data.getAttribute('data-index'); 1475 | 1476 | alert('not implemented yet') 1477 | } 1478 | }, 1479 | romance: { 1480 | partner() { 1481 | return player.relationships.partner[0] 1482 | }, 1483 | break() { 1484 | const exPartner = this.partner(); 1485 | exPartner.stats.relationWithPlayer -= 20 + Math.floor(Math.random() * 60) 1486 | exPartner.stats.loveToPartner = 0; 1487 | statsLimit(exPartner); 1488 | 1489 | exPartner.relationships.exPartners = []; 1490 | exPartner.relationships.exPartners.push(player); 1491 | exPartner.relationships.partner.pop(); 1492 | 1493 | player.relationships.exPartners = [] 1494 | player.relationships.exPartners.push(exPartner) 1495 | player.relationships.partner.pop(); 1496 | 1497 | eventBody.innerHTML = ` 1498 |You broke up with you ex
1499 |${pronoun} has accepted your marriage offer, now you are married
1512 |${pronoun} has rejected your marriage offer
1517 |You cuddled with ${pronoun}
1530 |You flirted with ${pronoun}
1543 |${pronoun} enjoyment
1565 |${player.pregnant ? 'You are' : 'She is'} pregnant
1582 | ${abort ? ` 1583 |${player.pregnant ? 'I am pregnant' : 'My partner is pregnant'}
1590 | ` 1591 | } 1592 | } 1593 | }, 1594 | abort() { 1595 | const partner = player.relationships.partner[0] 1596 | if (player.pregnant) player.pregnant = false 1597 | else partner.pregnant = false 1598 | eventBody.innerHTML = ` 1599 |We decided to abort it
1600 |You are currently ${player.sexuality}
1614 |I am ${sexuality} now
` 1625 | } 1626 | }, 1627 | driverLicense: { 1628 | display() { 1629 | if (player.age < 18) return; 1630 | 1631 | modalBackground.style.display = 'flex'; 1632 | eventTitle.innerText = 'Driver license' 1633 | eventBody.innerHTML = ` 1634 | ${player.driverLicense ? 'You already have a driver license
' : 'You dont have a driver license
'} 1635 | ` 1636 | eventBody.innerHTML += ` 1637 | ${!player.driverLicense ? ` 1638 |Congratulations, you approved the driver test
1648 |I approved the driver test succesfully
` 1651 | } else { 1652 | eventBody.innerHTML = `You failed the driver test, good luck the next time
1653 |I failed the driver test
` 1656 | } 1657 | }, 1658 | 1659 | }, 1660 | prison: { 1661 | display() { 1662 | showEvent({ 1663 | title: 'Prison', 1664 | body: ` 1665 |Years left: ${player.prison.yearsLeft} years
1666 |Sentence: ${player.prison.sentenceTime} years
1667 |I escaped from prison
1683 | ` 1684 | 1685 | } else { 1686 | player.prison.yearsLeft += 2; 1687 | player.prison.sentenceTime += 2 1688 | eventBody.innerHTML = ` 1689 |+2 years of prison
1691 |My escape attempt failed
1695 | ` 1696 | } 1697 | }, 1698 | lift() { 1699 | player.stats.fitness += 5; 1700 | statsLimit(player); 1701 | 1702 | eventBody.innerHTML = ` 1703 |You lifted
1704 |+5 fitness
1705 |I lifted
1709 | ` 1710 | } 1711 | }, 1712 | love: { 1713 | findLove() { 1714 | if (player.age < 14) return; 1715 | 1716 | if (player.relationships.partner.length !== 0) { 1717 | showEvent({ 1718 | title: 'Are you sure?', 1719 | body: ` 1720 |This means breaking up with your current partner
1721 |Name: ${possiblePartner.fullName}
1746 |Gender: ${capitalize(possiblePartner.gender)}
1747 |Age: ${possiblePartner.age}
1748 |Job: ${possiblePartner.job !== 'none' ? possiblePartner.job.label : 'unemployed'}
1749 | ${possiblePartner.job !== 'none' ? `Salary: ${moneyFormat(possiblePartner.job.salary)} $
` : ''} 1750 |${pronoun} is your partner now
1780 |${pronoun} has rejected you
1785 |You are already studying in the university
1804 |Im not going to the university
` 1825 | }, 1826 | chooseCareer(payer, paidBy) { 1827 | eventTitle.innerText = 'Choose your career'; 1828 | eventBody.innerHTML = ` 1829 | 1838 |I dont have enough money
` 1870 | let btn = document.getElementById('player-pay-university') 1871 | btn.remove() 1872 | } 1873 | }, 1874 | paidByParents() { 1875 | const dad = player.relationships.parents[0]; 1876 | const mom = player.relationships.parents[1]; 1877 | 1878 | if (dad.alive || mom.alive) 1879 | textContainer.innerHTML += `I asked my parents to pay
` 1880 | 1881 | if (dad.alive && dad.money.income - dad.money.expenses >= 6000 || 1882 | mom.alive && mom.money.income - mom.money.expenses >= 6000) { 1883 | textContainer.innerHTML += `My parents accepted
` 1884 | windows.university.chooseCareer(dad.alive && dad.money.income - dad.money.expenses >= 6000 ? dad : mom, 'parents'); 1885 | } else { 1886 | textContainer.innerHTML += `My parents rejected
` 1887 | let btn = document.getElementById('parents-pay-university') 1888 | btn.remove() 1889 | } 1890 | 1891 | }, 1892 | loan() { 1893 | textContainer.innerHTML += `I applied for a loan
` 1894 | windows.university.chooseCareer(undefined, 'loan'); 1895 | } 1896 | 1897 | }, 1898 | emigrate() { 1899 | const chosenCountry = document.getElementById('country-chooser').value 1900 | if (player.age >= 18) { 1901 | player.location = chosenCountry; 1902 | textContainer.innerHTML += ` 1903 |I emigrated to ${player.location}
1904 | ${player.job !== 'none' ? ` 1905 |I quit my job
` : ''} 1906 | `; 1907 | player.job.until = year; 1908 | player.money.income -= player.job.salary; 1909 | moneyViewer() 1910 | player.cv.push(player.job) 1911 | player.job = 'none' 1912 | menuTemplate.style.display = 'none'; 1913 | 1914 | 1915 | } else if (player.age < 18) { 1916 | showEvent({ 1917 | title: 'You cant emigrate', 1918 | body: ` 1919 |Will you quit?
1933 |Anual salary: ${moneyFormat(job.salary)}$
I got a job as ${job.label}
` 2000 | menu.job() 2001 | moneyViewer() 2002 | } else { 2003 | eventTitle.innerText = 'You did not get an interview' 2004 | eventBody.innerHTML = `Are you sure you want to leave?
2010 |You resigned succesfully
2021 |I worked harder at my job
2030 | ` 2031 | player.job.performance += Math.floor(Math.random() * 10) 2032 | player.stats.happiness -= 5 2033 | player.stats.health -= 2 2034 | player.actions.workHarder++; 2035 | statsLimit(player) 2036 | }, 2037 | askPromotion() { 2038 | player.actions.performance++ 2039 | modalBackground.style.display = 'flex' 2040 | eventTitle.innerText = 'Promotion' 2041 | if (player.job.performance >= 70) 2042 | for (let job of jobs) { 2043 | if (job.label === player.job.promotion) { 2044 | player.job.until = year 2045 | player.cv.push(player.job) 2046 | 2047 | player.job = structuredClone(job) 2048 | player.job.since = year 2049 | 2050 | eventBody.innerHTML = ` 2051 |Your promotion request has been accepted
2052 |Your promotion request has been rejected
2061 |Current job: ${player.job.label}
2070 |Salary: ${moneyFormat(player.job.salary)} $
2071 |Next position: TO DO
2072 |Years working: ${year - player.job.since}
2073 |Performance: ${player.job.performance}/100
2074 | 2077 |You do not have enough money
2099 |I watched a movie at a cinema
` 2162 | moneyViewer() 2163 | } else { 2164 | eventTitle.innerText = 'Cinema'; 2165 | eventBody.innerHTML = ` 2166 |I went to a restaurant
` 2197 | moneyViewer() 2198 | } else { 2199 | showEvent({ 2200 | title: "Restaurant", 2201 | body: ` 2202 |I went clubbing
2221 | ` 2222 | handleStatBars(player, true) 2223 | if (possibilities <= 1) 2224 | showEvent({ 2225 | title: "Go clubbing", 2226 | body: ` 2227 |You had fun at the club
2228 |You have been offered a ${drink}
2240 |I have been offered a ${drink}
` 2246 | } 2247 | else if (possibilities === 3) { 2248 | const drugs = [ 2249 | { 2250 | name: 'LSD', 2251 | damage: 5 2252 | }, 2253 | { 2254 | name: 'weed', 2255 | damage: 3 2256 | }, 2257 | { 2258 | name: 'heroin', 2259 | damage: 12 2260 | }, 2261 | { 2262 | name: 'cocaine', 2263 | damage: 10 2264 | } 2265 | ]; 2266 | const random = Math.floor(Math.random() * drugs.length) 2267 | const drug = drugs[random] 2268 | 2269 | textContainer.innerHTML += `I have been offered ${drug.name}
` 2270 | showEvent({ 2271 | title: "Go clubbing", 2272 | body: ` 2273 |You have been offered ${drug.name}
2274 |You accepted the ${drink}
2284 |I accepted the ${drink}
` 2287 | const random = Math.floor(Math.random() * 8) 2288 | player.stats.health -= random 2289 | statsLimit(player) 2290 | handleStatBars(player, true) 2291 | }, 2292 | acceptDrug(damage) { 2293 | menuTemplate.style.display = 'none' 2294 | closeEvent() 2295 | player.stats.health -= damage 2296 | statsLimit(player) 2297 | textContainer.innerHTML += `I accepted
` 2298 | handleStatBars(player, true) 2299 | }, 2300 | decline() { 2301 | menuTemplate.style.display = 'none' 2302 | closeEvent() 2303 | textContainer.innerHTML += ` 2304 |I declined
2305 | ` 2306 | } 2307 | }, 2308 | }, 2309 | handleRelationBars() { 2310 | let progressBars = document.getElementsByClassName('relation'); 2311 | for (let element of Object.entries(progressBars)) { 2312 | let index = parseInt(element[1].id.split('-')[1]) 2313 | let category = element[1].id.split('-')[0] 2314 | let opinion = player.relationships[category][index].stats.relationWithPlayer; 2315 | element[1].style.width = `${opinion}%` 2316 | } 2317 | 2318 | for (let progressBar of progressBars) { 2319 | let percentage = parseInt(progressBar.style.width.split('%')[0]); 2320 | if (percentage > 55) progressBar.style.backgroundColor = 'rgb(47, 151, 73)' 2321 | else if (percentage > 25) progressBar.style.backgroundColor = 'rgb(196, 221, 105)' 2322 | else progressBar.style.backgroundColor = 'rgb(185, 61, 61)' 2323 | } 2324 | }, 2325 | throwParty() { 2326 | player.stats.happiness += 10; 2327 | eventBody.innerHTML = ` 2328 |You threw an amazing party
2329 |I organized a party at home
` 2333 | statsLimit(player) 2334 | menuTemplate.style.display = 'none' 2335 | handleStatBars(player, true) 2336 | }, 2337 | } --------------------------------------------------------------------------------