Explorar el Código

Merge branch 'master' of https://git.tfgames.site/Kevin_Smarts/glife

Myles Croft (Hooded Silence) hace 3 meses
padre
commit
c077b26999
Se han modificado 36 ficheros con 969 adiciones y 365 borrados
  1. 352 299
      locations/drugs.qsrc
  2. 1 6
      locations/hourly_events.qsrc
  3. 2 2
      locations/intro_sg.qsrc
  4. 2 0
      locations/intro_sg_tg.qsrc
  5. 1 1
      locations/music_actions.qsrc
  6. 4 4
      locations/npcstatic4.qsrc
  7. 7 7
      locations/npcstatic5.qsrc
  8. 14 14
      locations/npcstatic6.qsrc
  9. 1 2
      locations/pirsingsalon.qsrc
  10. 9 9
      locations/pornfilm.qsrc
  11. 8 3
      locations/wardrobe.qsrc
  12. 10 2
      qsrc2tw/package-lock.json
  13. 1 0
      qsrc2tw/package.json
  14. 4 3
      qsrc2tw/tools/QSRC2TW/index.js
  15. 5 0
      qsrc2tw/tools/QSRC2TW/resources/QSP-functions/strpos.js
  16. 1 1
      qsrc2tw/tools/QSRC2TW/resources/QSP-macros/GT.js
  17. 1 0
      qsrc2tw/tools/QSRC2TW/resources/resources/Topbar.css
  18. 8 0
      qsrc2tw/tools/QSRC2TW/resources/resources/Topbar.tw
  19. 4 2
      qsrc2tw/tools/QSRC2TW/src/visitor/QsrcVisitor.js
  20. 81 0
      qsrc2tw/tools/QSRC2TW/src/wardrobeItems.js
  21. 22 9
      qsrc2tw/tools/QSRC2TW/task_processor.js
  22. 0 0
      qsrc2tw/tools/tweeGo/storyFormats/sugarcube-2/format.js
  23. 81 0
      qsrc2tw/twine-code/editor/Editor.css
  24. 15 0
      qsrc2tw/twine-code/editor/Editor.js
  25. 121 0
      qsrc2tw/twine-code/editor/Editor.tw
  26. 35 0
      qsrc2tw/twine-code/editor/diff.js
  27. 30 0
      qsrc2tw/twine-code/editor/save.js
  28. 14 0
      qsrc2tw/twine-code/external/_external.ts
  29. 8 0
      qsrc2tw/twine-code/external/ace.ts
  30. 5 0
      qsrc2tw/twine-code/external/diff.ts
  31. 5 0
      qsrc2tw/twine-code/external/jQueryUI.ts
  32. 40 0
      qsrc2tw/twine-code/misc/getPassageLinks.ts
  33. 30 0
      qsrc2tw/twine-code/misc/head.txt
  34. 1 1
      qsrc2tw/twine-code/start/begin.tw
  35. 10 0
      qsrc2tw/twine-code/twine-code.d.ts
  36. 36 0
      qsrc2tw/twine-code/ui/autoComplete.ts

+ 352 - 299
locations/drugs.qsrc

@@ -24,6 +24,7 @@ if $ARGS[0] = 'cikl':
 	gs 'drugs', 'aphrodisiac', 'cikl'
 	gs 'drugs', 'hair_extensioncream', 'cikl'
 	gs 'drugs', 'butt_injection', 'cikl'
+	exit
 
 elseif $ARGS[0] = 'hourly_events':
 	gs 'drugs', 'smoke', 'hourly_events'
@@ -32,12 +33,14 @@ elseif $ARGS[0] = 'hourly_events':
 	gs 'drugs', 'cocaine', 'hourly_events'
 	gs 'drugs', 'amphetamine', 'hourly_events'
 	gs 'drugs', 'aphrodisiac', 'hourly_events'
+	exit
 
 elseif $ARGS[0] = 'stat':
 	gs 'drugs', 'heroin', 'stat'
 	gs 'drugs', 'alcohol', 'stat'
 	gs 'drugs', 'cocaine', 'stat'
 	gs 'drugs', 'amphetamine', 'stat'
+	exit
 
 elseif $ARGS[0] = 'pain_relief':
 	if alko > 9:
@@ -55,86 +58,92 @@ elseif $ARGS[0] = 'pain_relief':
 	elseif pain['killer'] > 12 and alko <= 9:
 		pain['relief'] = 50
 	end
+	exit
+end
 
 
-elseif $ARGS[0] = 'smoke':
+if $ARGS[0] = 'smoke':
 	if $ARGS[1] = 'hourly_events':
-		if drugVars['cigarettes_used'] >= 20 and cheatVars['drugs_immune'] = 0: drugVars['cigarettes_need'] += 1
-		if drugVars['cigarettes_need'] > 10 and InSleep = 0 and pcs_mood > 20 and cheatVars['drugs_immune'] = 0: pcs_mood -= pcs_mood / 10
+		if cheatVars['drugs_immune'] = 0:
+			if drugVars['cigarettes_used'] >= 20: drugVars['cigarettes_need'] += 1
+			if drugVars['cigarettes_need'] > 10 and InSleep = 0 and pcs_mood > 20: pcs_mood -= pcs_mood / 10
+		end
 
 		if drugVars['cigarettes_need'] > 300:
 			drugVars['cigarettes_need'] = 0
 			drugVars['cigarettes_used'] = 0
 		end
-	else
-		if ARGS[1] = 0 and $ARGS[1] = '':
-			mc_inventory['cigarettes'] -= 1
-			if mc_inventory['cigarettes'] <= 0: mc_inventory['cigarettes'] = 0 & msg 'That was your last cigarette.'
-		end
+		exit
+	end
 
-		if cheatVars['drugs_immune'] = 1:
-			drugVars['cigarettes_used'] += 1
-			if drugVars['cigarettes_used'] > 20 and drugVars['cigarettes_exp'] = 0: drugVars['cigarettes_exp'] = 1
-		end
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['cigarettes'] -= 1
+		if mc_inventory['cigarettes'] <= 0: mc_inventory['cigarettes'] = 0 & msg 'That was your last cigarette.'
+	end
 
-		stat['cigarettes_smoked'] += 1
-		drugVars['cigarettes_day'] = daystart
-		drugVars['cigarettes_hour'] = hour
-		drugVars['cigarettes_minute'] = minut + 3
-		drugVars['cigarettes_need'] = 0
-		teeth['smoked'] += 1
-
-		pcs_breath = 0
-		pcs_mood += 100
-		if pcs_hydra >= 100:
-			pcs_hydra -= 5
-		else
-			pcs_hydra -= 10
-		end
-		if pcs_energy < 80: pcs_energy += 4
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['cigarettes_used'] += 1
+		if drugVars['cigarettes_used'] > 20 and drugVars['cigarettes_exp'] = 0: drugVars['cigarettes_exp'] = 1
+	end
 
-		cumspclnt = 2
-		gs 'cum_cleanup'
-		gs 'stat'
+	stat['cigarettes_smoked'] += 1
+	drugVars['cigarettes_day'] = daystart
+	drugVars['cigarettes_hour'] = hour
+	drugVars['cigarettes_minute'] = minut + 3
+	drugVars['cigarettes_need'] = 0
+	teeth['smoked'] += 1
+
+	pcs_breath = 0
+	pcs_mood += 100
+	if pcs_hydra >= 100:
+		pcs_hydra -= 5
+	else
+		pcs_hydra -= 10
 	end
+	if pcs_energy < 80: pcs_energy += 4
+
+	cumspclnt = 2
+	gs 'cum_cleanup'
+	gs 'stat'
 
 
 elseif $ARGS[0] = 'joint':
 	if $ARGS[1] = 'hourly_events':
 		if drugVars['weed_high'] > 0: drugVars['weed_high'] -= 1
-	else
-		if ARGS[1] = 0 and $ARGS[1] = '':
-			mc_inventory['joints'] -= 1
-			if mc_inventory['joints'] <= 0: mc_inventory['joints'] = 0 & msg 'That was your last joint.'
-		end
+		exit
+	end
 
-		if cheatVars['drugs_immune'] = 0:
-			drugVars['weed_used'] += 1
-			if drugVars['weed_used'] > 5 and drugVars['weed_exp'] = 0: drugVars['weed_exp'] = 1
-		end
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['joints'] -= 1
+		if mc_inventory['joints'] <= 0: mc_inventory['joints'] = 0 & msg 'That was your last joint.'
+	end
 
-		if minut > 30:
-			drugVars['weed_high'] = 2
-		else
-			drugVars['weed_high'] = 1
-		end
-		drugVars['weed_day'] = daystart
-		drugVars['weed_hour'] = hour
-		drugVars['weed_minute'] = minut + 2
-
-		pcs_breath = 0
-		pcs_mood += 100
-		if pcs_hydra >= 100:
-			pcs_hydra -= 5
-		else
-			pcs_hydra -= 10
-		end
-		pcs_energy = max(0, pcs_energy - 20)
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['weed_used'] += 1
+		if drugVars['weed_used'] > 5 and drugVars['weed_exp'] = 0: drugVars['weed_exp'] = 1
+	end
 
-		cumspclnt = 2
-		gs 'cum_cleanup'
-		gs 'stat'
+	if minut > 30:
+		drugVars['weed_high'] = 2
+	else
+		drugVars['weed_high'] = 1
 	end
+	drugVars['weed_day'] = daystart
+	drugVars['weed_hour'] = hour
+	drugVars['weed_minute'] = minut + 2
+
+	pcs_breath = 0
+	pcs_mood += 100
+	if pcs_hydra >= 100:
+		pcs_hydra -= 5
+	else
+		pcs_hydra -= 10
+	end
+	pcs_energy = max(0, pcs_energy - 20)
+
+	cumspclnt = 2
+	gs 'cum_cleanup'
+	gs 'stat'
 
 
 elseif $ARGS[0] = 'heroin':
@@ -152,6 +161,7 @@ elseif $ARGS[0] = 'heroin':
 			drugVars['heroin_need'] = 0
 			drugVars['heroin_used'] = 0
 		end
+		exit
 	elseif $ARGS[1] = 'stat':
 		if drugVars['heroin_high'] >= 20 and alko > 0: alko = 0
 		if drugVars['heroin_high'] <= 0:
@@ -164,20 +174,21 @@ elseif $ARGS[0] = 'heroin':
 			if drugVars['heroin_penalty'] > 0: vidage += 1
 			drugVars['heroin_penalty'] += 1
 		end
-	else
-		if cheatVars['drugs_immune'] = 0:
-			drugVars['heroin_used'] += 1
-			if drugVars['heroin_used'] > 1 and drugVars['heroin_exp'] = 0: drugVars['heroin_exp'] = 1
-		end
-
-		drugVars['heroin_high'] += 25
-		drugVars['heroin_day'] = daystart
+		exit
+	end
 
-		pcs_mood = 100
-		pcs_health -= 10
-		gs 'stat'
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['heroin_used'] += 1
+		if drugVars['heroin_used'] > 1 and drugVars['heroin_exp'] = 0: drugVars['heroin_exp'] = 1
 	end
 
+	drugVars['heroin_high'] += 25
+	drugVars['heroin_day'] = daystart
+
+	pcs_mood = 100
+	pcs_health -= 10
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'cocaine':
 	if $ARGS[1] = 'cikl':
@@ -188,6 +199,7 @@ elseif $ARGS[0] = 'cocaine':
 		elseif drugVars['cocaine_system'] > 0:
 			drugVars['cocaine_system'] -= 1
 		end
+		exit
 	elseif $ARGS[1] = 'hourly_events':
 		if drugVars['cocaine_addict'] = 1 and drugVars['cocaine_day'] ! daystart:
 			pcs_health -= 5
@@ -199,34 +211,37 @@ elseif $ARGS[0] = 'cocaine':
 				pcs_mood = 5
 			end
 		end
+		exit
 	elseif $ARGS[1] = 'stat':
 		if cheatVars['drugs_immune'] = 1:
 			if drugVars['cocaine_addict'] ! 0: drugVars['cocaine_addict'] = 0
-		elseif drugVars['cocaine_system'] >= 30 and drugVars['cocaine_addict'] = 0 and cheatVars['drugs_immune'] = 0:
+		elseif drugVars['cocaine_system'] >= 30 and drugVars['cocaine_addict'] = 0:
 			drugVars['cocaine_addict'] = 1
 		elseif drugVars['cocaine_system'] = 0 and drugVars['cocaine_addict'] = 1:
 			drugVars['cocaine_addict'] = 0
 		end
-	else
-		if ARGS[1] = 0 and $ARGS[1] = '':
-			mc_inventory['cocaine'] -= 1
-			if mc_inventory['cocaine'] <= 0: mc_inventory['cocaine'] = 0 & msg 'That was your last line of cocaine.'
-		end
-		if cheatVars['drugs_immune'] = 0:
-			drugVars['cocaine_used'] += 1
-			if drugVars['cocaine_used'] > 3 and drugVars['cocaine_exp'] = 0: drugVars['cocaine_exp'] = 1
-		end
+		exit
+	end
 
-		drugVars['cocaine_system'] += 10
-		drugVars['cocaine_day'] = daystart
-		if drugVars['cocaine_willday'] ! daystart: drugVars['cocaine_willday'] = daystart & pcs_willpwr += 10
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['cocaine'] -= 1
+		if mc_inventory['cocaine'] <= 0: mc_inventory['cocaine'] = 0 & msg 'That was your last line of cocaine.'
+	end
 
-		pcs_health = pcs_vital * 10 + pcs_stren * 5
-		pcs_mood = 100
-		pcs_horny = 100
-		gs 'stat'
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['cocaine_used'] += 1
+		if drugVars['cocaine_used'] > 3 and drugVars['cocaine_exp'] = 0: drugVars['cocaine_exp'] = 1
 	end
 
+	drugVars['cocaine_system'] += 10
+	drugVars['cocaine_day'] = daystart
+	if drugVars['cocaine_willday'] ! daystart: drugVars['cocaine_willday'] = daystart & pcs_willpwr += 10
+
+	pcs_health = pcs_vital * 10 + pcs_stren * 5
+	pcs_mood = 100
+	pcs_horny = 100
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'amphetamine':
 	if $ARGS[1] = 'hourly_events':
@@ -282,6 +297,7 @@ elseif $ARGS[0] = 'amphetamine':
 			drugVars['amphetamine_bonus'] = 1
 			drugVars['amphetamine_used'] = 0
 		end
+		exit
 
 	elseif $ARGS[1] = 'stat':
 		if drugVars['amphetamine_used'] > 3 and drugVars['amphetamine_high'] <= 0:
@@ -291,27 +307,30 @@ elseif $ARGS[0] = 'amphetamine':
 			end
 			killvar 'temp_addictChance'
 		end
-	else
-		if drugVars['amphetamine_intake'] >= 2:
-			'Your heart is already beating uncontrollably in your chest, you should avoid taking anymore pills.'
-		else
-			'<font color= blue>You swallow the white pill.</font>'
+		exit
+	end
 
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['amphetamine'] -= 1
-				if mc_inventory['amphetamine'] <= 0: mc_inventory['amphetamine'] = 0 & msg 'That was your last amphetamine pill.'
-			end
-			if cheatVars['drugs_immune'] = 0:
-				drugVars['amphetamine_used'] += 1
-				if drugVars['amphetamine_used'] > 5 and drugVars['amphetamine_exp'] = 0: drugVars['amphetamine_exp'] = 1
-			end
+	if drugVars['amphetamine_intake'] >= 2:
+		'Your heart is already beating uncontrollably in your chest, you should avoid taking anymore pills.'
+		exit
+	end
 
-			drugVars['amphetamine_intake'] += 1
-			drugVars['amphetamine_high'] = 12
-		end
-		gs 'stat'
+	'<font color= blue>You swallow the white pill.</font>'
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['amphetamine'] -= 1
+		if mc_inventory['amphetamine'] <= 0: mc_inventory['amphetamine'] = 0 & msg 'That was your last amphetamine pill.'
 	end
 
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['amphetamine_used'] += 1
+		if drugVars['amphetamine_used'] > 5 and drugVars['amphetamine_exp'] = 0: drugVars['amphetamine_exp'] = 1
+	end
+
+	drugVars['amphetamine_intake'] += 1
+	drugVars['amphetamine_high'] = 12
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'mentats':
 	if $ARGS[1] = 'cikl':
@@ -321,16 +340,21 @@ elseif $ARGS[0] = 'mentats':
 			pain['head'] += 20 * drugVars['mentats_dose']
 			drugVars['mentats_dose'] = 0
 		end
-	else
-		if ARGS[1] = 0 and $ARGS[1] = '':
-			mc_inventory['mentats'] -= 1
-			if mc_inventory['mentats'] <= 0: mc_inventory['mentats'] = 0 & msg 'That was your last neurobooster pill.'
-		end
+		exit
+	end
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['mentats'] -= 1
+		if mc_inventory['mentats'] <= 0: mc_inventory['mentats'] = 0 & msg 'That was your last neurobooster pill.'
+	end
+
+	if cheatVars['drugs_immune'] = 0:
 		drugVars['mentats_used'] += 1
-		drugVars['mentats_dose'] += 1
-		gs 'stat'
 	end
 
+	drugVars['mentats_dose'] += 1
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'steroids':
 	if $ARGS[1] = 'cikl':
@@ -341,23 +365,28 @@ elseif $ARGS[0] = 'steroids':
 			end
 			drugVars['steroids_dose'] = 0
 		end
-	else
-		if drugVars['steroids_dose'] < 3:
-			'<font color = blue>You swallow the orange pill.</font>'
+		exit
+	end
 
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['steroids'] -= 1
-				if mc_inventory['steroids'] <= 0: mc_inventory['steroids'] = 0 & msg 'That was your last steroid pill.'
-			end
+	if drugVars['steroids_dose'] >= 3:
+		'You really shouldn''t take any more pills today.'
+		exit
+	end
 
-			drugVars['steroids_used'] += 1
-			drugVars['steroids_dose'] += 1
-		else
-			'You really shouldn''t take any more pills today.'
-		end
-		gs 'stat'
+	'<font color = blue>You swallow the orange pill.</font>'
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['steroids'] -= 1
+		if mc_inventory['steroids'] <= 0: mc_inventory['steroids'] = 0 & msg 'That was your last steroid pill.'
 	end
 
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['steroids_used'] += 1
+	end
+
+	drugVars['steroids_dose'] += 1
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'breastcream':
 	if $ARGS[1] = 'cikl':
@@ -373,23 +402,28 @@ elseif $ARGS[0] = 'breastcream':
 			end
 			killvar 'temp'
 		end
-	else
-		if drugVars['breastcream_dose'] < 1:
-			'<font color = #DB7093>You smear the cream onto your breasts and rub it in.</font>'
+		exit
+	end
 
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['breastcream'] -= 1
-				if mc_inventory['breastcream'] <= 0: mc_inventory['breastcream'] = 0 & msg 'That was your last bit of breast cream.'
-			end
+	if drugVars['breastcream_dose'] >= 1:
+		'Using any more cream won''t have any effect.'
+		exit
+	end
 
-			drugVars['breastcream_used'] += 1
-			drugVars['breastcream_dose'] = 1
-		else
-			'Using any more cream won''t have any effect.'
-		end
-		gs 'stat'
+	'<font color = #DB7093>You smear the cream onto your breasts and rub it in.</font>'
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['breastcream'] -= 1
+		if mc_inventory['breastcream'] <= 0: mc_inventory['breastcream'] = 0 & msg 'That was your last bit of breast cream.'
 	end
 
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['breastcream_used'] += 1
+	end
+
+	drugVars['breastcream_dose'] = 1
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'painkiller':
 	if ARGS[1] = 0 and $ARGS[1] = '':
@@ -397,7 +431,10 @@ elseif $ARGS[0] = 'painkiller':
 		if mc_inventory['painkillers'] <= 0: mc_inventory['painkillers'] = 0 & msg 'That was your last painkiller.'
 	end
 
-	drugVars['painkillers_used'] += 1
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['painkillers_used'] += 1
+	end
+
 	pain['killer'] += 1
 	gs 'stat'
 
@@ -411,111 +448,113 @@ elseif $ARGS[0] = 'alcohol':
 		elseif alko > 3:
 			pain['relief'] = 15
 		end
+		exit
+	end
+
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['alcohol_used'] += 1
+		if drugVars['alcohol_used'] > 15 and drugVars['alcohol_exp'] = 0: drugVars['alcohol_exp'] = 1
+	end
+
+	if ARGS[2] <= 1:
+		temp_alc_count = 1
 	else
-		if cheatVars['drugs_immune'] = 0:
-			drugVars['alcohol_used'] += 1
-			if drugVars['alcohol_used'] > 15 and drugVars['alcohol_exp'] = 0: drugVars['alcohol_exp'] = 1
-		end
+		temp_alc_count = ARGS[2]
+	end
 
-		if ARGS[2] <= 1:
-			temp_alc_count = 1
-		else
-			temp_alc_count = ARGS[2]
-		end
+	:alcohol_jump
+		temp_alc_count -= 1
+		pcs_health -= 5
+		pcs_energy -= 5
 
-		:alcohol_jump
-			temp_alc_count -= 1
-			pcs_health -= 5
-			pcs_energy -= 5
-
-			if $ARGS[1] = 'beer':
-				if pcs_traits['alko_status'] = -1:
-					alko += rand(1,2)
-				elseif pcs_traits['alko_status'] = 1:
-					alko += rand(0,1)
-				else
-					alko += 1
-				end
-				pcs_traits['alko_day'] += 1
-
-				fat += 3
-				pcs_mood += 10
-				if pcs_hydra >= 100:
-					pcs_hydra += 5
-				else
-					pcs_hydra += 10
-				end
-
-			elseif $ARGS[1] = 'wine' or $ARGS[1] = 'champagne':
-				if pcs_traits['alko_status'] = -1:
-					alko += 3
-				elseif pcs_traits['alko_status'] = 1:
-					alko += 1
-				else
-					alko += 2
-				end
-				pcs_traits['alko_day'] += 2
-
-				fat += 4
-				pcs_mood += 20
-				if pcs_hydra >= 100:
-					pcs_hydra += 5
-				else
-					pcs_hydra += 10
-				end
-
-			elseif $ARGS[1] = 'vodka' or $ARGS[1] = 'whiskey' or $ARGS[1] = 'scotch' or $ARGS[1] = 'rum':
-				if pcs_traits['alko_status'] = -1:
-					alko += rand(4,5)
-				elseif pcs_traits['alko_status'] = 1:
-					alko += rand(1,2)
-				else
-					alko += 3
-				end
-				pcs_traits['alko_day'] += 3
-
-				fat += 6
-				if pcs_hydra >= 100:
-					pcs_hydra -= 5
-				else
-					pcs_hydra -= 10
-				end
-
-			elseif $ARGS[1] = 'moonshine':
-				if pcs_traits['alko_status'] = -1:
-					alko += rand(7,8)
-				elseif pcs_traits['alko_status'] = 1:
-					alko += rand(2,3)
-				else
-					alko += 5
-				end
-				pcs_traits['alko_day'] += 5
-
-				fat += 6
-				if pcs_hydra >= 100:
-					pcs_hydra -= 5
-				else
-					pcs_hydra -= 10
-				end
+		if $ARGS[1] = 'beer':
+			if pcs_traits['alko_status'] = -1:
+				alko += rand(1,2)
+			elseif pcs_traits['alko_status'] = 1:
+				alko += rand(0,1)
+			else
+				alko += 1
+			end
+			pcs_traits['alko_day'] += 1
 
+			fat += 3
+			pcs_mood += 10
+			if pcs_hydra >= 100:
+				pcs_hydra += 5
 			else
-				'<br><font color = red>Developer note: The type of alcohol: (<<$ARGS[1]>>) is missing in this scene. Please report this and a small part of the text of the current scene as a bug.</font>'
+				pcs_hydra += 10
 			end
-		if temp_alc_count > 0: jump 'alcohol_jump'
-		killvar 'temp_alc_count'
 
-		frost = 0
-		pcs_breath = 0
-		cumspclnt = 2
-		gs 'cum_cleanup'
-		gs 'stat'
-	end
+		elseif $ARGS[1] = 'wine' or $ARGS[1] = 'champagne':
+			if pcs_traits['alko_status'] = -1:
+				alko += 3
+			elseif pcs_traits['alko_status'] = 1:
+				alko += 1
+			else
+				alko += 2
+			end
+			pcs_traits['alko_day'] += 2
+
+			fat += 4
+			pcs_mood += 20
+			if pcs_hydra >= 100:
+				pcs_hydra += 5
+			else
+				pcs_hydra += 10
+			end
+
+		elseif $ARGS[1] = 'vodka' or $ARGS[1] = 'whiskey' or $ARGS[1] = 'scotch' or $ARGS[1] = 'rum':
+			if pcs_traits['alko_status'] = -1:
+				alko += rand(4,5)
+			elseif pcs_traits['alko_status'] = 1:
+				alko += rand(1,2)
+			else
+				alko += 3
+			end
+			pcs_traits['alko_day'] += 3
+
+			fat += 6
+			if pcs_hydra >= 100:
+				pcs_hydra -= 5
+			else
+				pcs_hydra -= 10
+			end
+
+		elseif $ARGS[1] = 'moonshine':
+			if pcs_traits['alko_status'] = -1:
+				alko += rand(7,8)
+			elseif pcs_traits['alko_status'] = 1:
+				alko += rand(2,3)
+			else
+				alko += 5
+			end
+			pcs_traits['alko_day'] += 5
+
+			fat += 6
+			if pcs_hydra >= 100:
+				pcs_hydra -= 5
+			else
+				pcs_hydra -= 10
+			end
+
+		else
+			'<br><font color = red>Developer note: The type of alcohol: (<<$ARGS[1]>>) is missing in this scene. Please report this and a small part of the text of the current scene as a bug.</font>'
+		end
+	if temp_alc_count > 0: jump 'alcohol_jump'
+	killvar 'temp_alc_count'
+
+	frost = 0
+	pcs_breath = 0
+	cumspclnt = 2
+	gs 'cum_cleanup'
+	gs 'stat'
 
 
 elseif $ARGS[0] = 'aphrodisiac':
 	if $ARGS[1] = 'cikl':
 		if drugVars['aphrodisiac_overdose'] = 1: drugVars['aphrodisiac_overdose'] = 0
 		if drugVars['aphrodisiac_timer'] ! 0: drugVars['aphrodisiac_timer']	= 0
+		exit
 	elseif $ARGS[1] = 'hourly_events':
 		if drugVars['aphrodisiac_timer'] >= 1:
 			!! Changed from pcs_horny < 80 -> pcs_horny < 70 to ensure a minimum increase of +10. Blame Anjuna
@@ -526,53 +565,57 @@ elseif $ARGS[0] = 'aphrodisiac':
 			end
 			drugVars['aphrodisiac_timer'] -= 1
 		end
-	else
-		if drugVars['aphrodisiac_overdose'] = 1:
-			$drugVars['aphrodisiac_msg'] = '<br>You''ve had enough aphrodisiac for today.'
-		else
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['aphrodisiac'] -= 1
-				if mc_inventory['aphrodisiac'] <= 0: mc_inventory['aphrodisiac'] = 0 & msg 'That was your last aphrodisiac pill.'
-			end
+		exit
+	end
 
-			drugVars['aphrodisiac_used'] += 1
+	if drugVars['aphrodisiac_overdose'] = 1:
+		$drugVars['aphrodisiac_msg'] = '<br>You''ve had enough aphrodisiac for today.'
+		exit
+	end
 
-			if drugVars['aphrodisiac_timer'] = 0:
-				$drugVars['aphrodisiac_msg'] = '<font color = #DB7093><br>You take a gum and chew it. It tastes like strawberry, but is also kind of spicy.</font>'
-				drugVars['aphrodisiac_timer'] += 8
-				pcs_horny = 80
-			elseif drugVars['aphrodisiac_timer'] > 0 and drugVars['aphrodisiac_timer'] <= 8:
-				$drugVars['aphrodisiac_msg'] = '<font color = #DB7093><br>You take another gum and chew it. It makes your mouth feel kinda tingly.</font>'
-				drugVars['aphrodisiac_timer'] += 8
-				pcs_horny = 100
-			elseif drugVars['aphrodisiac_timer'] > 8 and min_arousal < 60:
-				$drugVars['aphrodisiac_msg'] = '<font color = red><b><br>You take yet another gum and start chewing it. Suddenly you find yourself in grip of an intense orgasm!<br>It goes on and on and you sink to the ground and do your best to endure it.</b></font>'
-				drugVars['aphrodisiac_overdose'] = 1
-				pcs_horny = min_arousal
-
-				orgasm += 1
-				pcs_mood = 100
-				min_arousal += 10
-
-				if min_arousal <= 10:
-					$min_arousal_msg = '<font color = #DB7093>That was intense! You can still feel the tingles.</font>'
-				elseif min_arousal <= 20:
-					$min_arousal_msg = '<font color = #DB7093>You are really starting to enjoy these! Your crotch still feels kinda hot though.</font>'
-				elseif min_arousal <= 30:
-					$min_arousal_msg = '<font color = #DB7093>As you are trying to get back to your feet you notice that you are still horny. What is happening to you?</font>'
-				elseif min_arousal <= 40:
-					$min_arousal_msg = '<font color = #DB7093>You are certain of it. Every time those gums give you an orgasm they also increase your libido.</font>'
-				elseif min_arousal <= 50:
-					$min_arousal_msg = '<font color = #DB7093>You run a finger across your slit and shudder. You really should stop chewing these gums while you can still think of something other than sex.</font>'
-				else
-					$min_arousal_msg = '<font color = #DB7093>You are burning up. You feel like you could fuck anything and everything all day long.</font>'
-				end
-			else
-				$drugVars['aphrodisiac_msg'] = '<font color = #DB7093>You chew another gum with trepidation, looking forward to more orgasms but nothing happens. Huh. Have you become immune?</font>'
-			end
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['aphrodisiac'] -= 1
+		if mc_inventory['aphrodisiac'] <= 0: mc_inventory['aphrodisiac'] = 0 & msg 'That was your last aphrodisiac pill.'
+	end
+
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['aphrodisiac_used'] += 1
+	end
+
+	if drugVars['aphrodisiac_timer'] = 0:
+		$drugVars['aphrodisiac_msg'] = '<font color = #DB7093><br>You take a gum and chew it. It tastes like strawberry, but is also kind of spicy.</font>'
+		drugVars['aphrodisiac_timer'] += 8
+		pcs_horny = 80
+	elseif drugVars['aphrodisiac_timer'] > 0 and drugVars['aphrodisiac_timer'] <= 8:
+		$drugVars['aphrodisiac_msg'] = '<font color = #DB7093><br>You take another gum and chew it. It makes your mouth feel kinda tingly.</font>'
+		drugVars['aphrodisiac_timer'] += 8
+		pcs_horny = 100
+	elseif drugVars['aphrodisiac_timer'] > 8 and min_arousal < 60:
+		$drugVars['aphrodisiac_msg'] = '<font color = red><b><br>You take yet another gum and start chewing it. Suddenly you find yourself in grip of an intense orgasm!<br>It goes on and on and you sink to the ground and do your best to endure it.</b></font>'
+		drugVars['aphrodisiac_overdose'] = 1
+		pcs_horny = min_arousal
+
+		orgasm += 1
+		pcs_mood = 100
+		min_arousal += 10
+
+		if min_arousal <= 10:
+			$min_arousal_msg = '<font color = #DB7093>That was intense! You can still feel the tingles.</font>'
+		elseif min_arousal <= 20:
+			$min_arousal_msg = '<font color = #DB7093>You are really starting to enjoy these! Your crotch still feels kinda hot though.</font>'
+		elseif min_arousal <= 30:
+			$min_arousal_msg = '<font color = #DB7093>As you are trying to get back to your feet you notice that you are still horny. What is happening to you?</font>'
+		elseif min_arousal <= 40:
+			$min_arousal_msg = '<font color = #DB7093>You are certain of it. Every time those gums give you an orgasm they also increase your libido.</font>'
+		elseif min_arousal <= 50:
+			$min_arousal_msg = '<font color = #DB7093>You run a finger across your slit and shudder. You really should stop chewing these gums while you can still think of something other than sex.</font>'
+		else
+			$min_arousal_msg = '<font color = #DB7093>You are burning up. You feel like you could fuck anything and everything all day long.</font>'
 		end
-		gs 'stat'
+	else
+		$drugVars['aphrodisiac_msg'] = '<font color = #DB7093>You chew another gum with trepidation, looking forward to more orgasms but nothing happens. Huh. Have you become immune?</font>'
 	end
+	gs 'stat'
 
 
 elseif $ARGS[0] = 'hair_extensioncream':
@@ -585,23 +628,28 @@ elseif $ARGS[0] = 'hair_extensioncream':
 				'Feels like your hair has grown slightly.'
 			end
 		end
-	else
-		if drugVars['hair_extensioncream_dose'] < 1:
-			'<font color = #DB7093>You smear the shampoo into your hair and rub it in, then wash it out shortly later.</font>'
+		exit
+	end
 
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['hair_extensioncream'] -= 1
-				if mc_inventory['hair_extensioncream'] <= 0: mc_inventory['hair_extensioncream'] = 0 & msg 'That was your last bit of hair extension shampoo.'
-			end
+	if drugVars['hair_extensioncream_dose'] >= 1:
+		'Using any more hair extension shampoo won''t have any effect.'
+		exit
+	end
 
-			drugVars['hair_extensioncream_used'] += 1
-			drugVars['hair_extensioncream_dose'] = 1
-		else
-			'Using any more hair extension shampoo won''t have any effect.'
-		end
-		gs 'stat'
+	'<font color = #DB7093>You smear the shampoo into your hair and rub it in, then wash it out shortly later.</font>'
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['hair_extensioncream'] -= 1
+		if mc_inventory['hair_extensioncream'] <= 0: mc_inventory['hair_extensioncream'] = 0 & msg 'That was your last bit of hair extension shampoo.'
 	end
 
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['hair_extensioncream_used'] += 1
+	end
+
+	drugVars['hair_extensioncream_dose'] = 1
+	gs 'stat'
+
 
 elseif $ARGS[0] = 'butt_injection':
 	if $ARGS[1] = 'cikl':
@@ -617,23 +665,28 @@ elseif $ARGS[0] = 'butt_injection':
 			end
 			killvar 'temp'
 		end
-	else
-		if drugVars['butt_injection_dose'] < 1:
-			'<font color = #DB7093>You inject the KBI formula into your ass.</font>'
+		exit
+	end
 
-			if ARGS[1] = 0 and $ARGS[1] = '':
-				mc_inventory['butt_injection'] -= 1
-				if mc_inventory['butt_injection'] <= 0: mc_inventory['butt_injection'] = 0 & msg 'That was your last KBI shot.'
-			end
+	if drugVars['butt_injection_dose'] >= 1:
+		'Using any more injections won''t have any effect.'
+		exit
+	end
 
-			drugVars['butt_injection_used'] += 1
-			drugVars['butt_injection_dose'] = 1
-		else
-			'Using any more injections won''t have any effect.'
-		end
-		gs 'stat'
+	'<font color = #DB7093>You inject the KBI formula into your ass.</font>'
+
+	if ARGS[1] = 0 and $ARGS[1] = '':
+		mc_inventory['butt_injection'] -= 1
+		if mc_inventory['butt_injection'] <= 0: mc_inventory['butt_injection'] = 0 & msg 'That was your last KBI shot.'
+	end
+
+	if cheatVars['drugs_immune'] = 0:
+		drugVars['butt_injection_used'] += 1
 	end
 
+	drugVars['butt_injection_dose'] = 1
+	gs 'stat'
+
 
 else
 	'<br><font color = red>Developer note: The type of drug is wrong or missing in this scene. Please report this and a small part of the text of the current scene as a bug.</font>'

+ 1 - 6
locations/hourly_events.qsrc

@@ -96,12 +96,7 @@ else
 	pcs_willpower_feeder = pcs_willpower_feeder mod 100
 end
 
-gs 'drugs', 'smoke', 'hourly_events'
-gs 'drugs', 'joint', 'hourly_events'
-gs 'drugs', 'heroin', 'hourly_events'
-gs 'drugs', 'cocaine', 'hourly_events'
-gs 'drugs', 'amphetamine', 'hourly_events'
-gs 'drugs', 'aphrodisiac', 'hourly_events'
+gs 'drugs', 'hourly_events'
 
 
 !!=======================================================!!

+ 2 - 2
locations/intro_sg.qsrc

@@ -83,7 +83,7 @@ if $ARGS[0] = 'intro_pavlovsk':
 	'<center><img <<$set_imgh>> src="images/characters/pavlovsk/resident/mom/prost4.jpg"></center>'
 	'You suddenly hear a familiar voice yelling out. "<<$pcs_nickname>>, time to get up! You can''t spend the whole day laying around!"'
 	wait 1000
-	gs 'intro_sg', 'set_mother_nickname'
+	if $start_type['magic'] ! 'tg': gs 'intro_sg', 'set_mother_nickname'
 
 	act 'Continue':
 		*clr & cla
@@ -152,7 +152,7 @@ if $ARGS[0] = 'intro_gadukino':
 	*nl
 	'You suddenly hear a familiar voice yelling. "<<$pcs_nickname>>, time to get up. You can''t spend the whole day lying around!"'
 	wait 1000
-	gs 'intro_sg', 'set_mother_nickname'
+	if $start_type['magic'] ! 'tg': gs 'intro_sg', 'set_mother_nickname'
 
 	act 'Continue':
 		*clr & cla

+ 2 - 0
locations/intro_sg_tg.qsrc

@@ -199,6 +199,8 @@ if $ARGS[0] = 'settings':
 
 	gs 'intro_functions', 'set_base_stats'
 
+	kanikuli = 5
+
 	!!----- SKILLS -----!!
 	! Attributes
 	pcs_stren		= 30

+ 1 - 1
locations/music_actions.qsrc

@@ -331,7 +331,7 @@ if $ARGS[0] = 'willpower_cost':
         else
             $diff = 'easy'
         end
-        gs 'willpower', 'skill', 'self', pcs_perform, $diff
+        gs 'willpower', 'skill', 'self', 'pcs_perform', $diff
     end
 end
 

+ 4 - 4
locations/npcstatic4.qsrc

@@ -900,8 +900,8 @@ $npc_firstname['A<<npctemp>>'] = 'Alexander'
 $npc_nickname['A<<npctemp>>'] = 'Alexei'
 $npc_lastname['A<<npctemp>>'] = 'Radimov'
 $npc_usedname['A<<npctemp>>'] = 'Porn actor Alexei Radimov'
-$npc_notes['A<<npctemp>>'] = 'Alexei has worked in porn ever since he lost his job as a steel worker. He is divorced with twin teenage daughters and only planned to do porn as a temporary thing to pay for their university studies, but eventually chose to make it permanent since it earned him more money than any other job could offer. He is sellable too, being almost two meters tall and built like a tank.'
-npc_dob['A<<npctemp>>'] = 19721110
+$npc_notes['A<<npctemp>>'] = 'Alexei is a former steel plant worker. He is divorced with twin teenage daughters and ended up doing porn to pay for their university studies since it earned him more money than any other job could offer. He is sellable too, being almost two meters tall and built like a tank.'
+npc_dob['A<<npctemp>>'] = 19710610
 npc_gender['A<<npctemp>>'] = 0
 
 gs 'npcstaticdefaults', 'defaults'
@@ -918,7 +918,7 @@ npc_spermpot['A<<npctemp>>'] = 12000
 npctemp = 194
 $npc_dna['A<<npctemp>>'] = '7008670756 7958693370 7059741341 1566986214 1732880506 1281239619 1634169768'
 $npc_firstname['A<<npctemp>>'] = 'Sergei'
-$npc_nickname['A<<npctemp>>'] = 'Seryozha'
+$npc_nickname['A<<npctemp>>'] = 'Sergei'
 $npc_lastname['A<<npctemp>>'] = 'Tatarov'
 $npc_usedname['A<<npctemp>>'] = 'Porn actor Sergei Tatarov'
 $npc_notes['A<<npctemp>>'] = 'Sergei is smooth, charming and handsome, but a real asshole. Nobody likes to work with him, but he is a true professional and a really good actor. There are rumors about him raping a schoolgirl, but nobody knows anything about it.'
@@ -938,7 +938,7 @@ npc_spermpot['A<<npctemp>>'] = 10000
 npctemp = 195
 $npc_dna['A<<npctemp>>'] = '1086487692 7476661390 7698010724 1870038241 1870978496 1236988759 1677200479'
 $npc_firstname['A<<npctemp>>'] = 'Egor'
-$npc_nickname['A<<npctemp>>'] = 'Egori'
+$npc_nickname['A<<npctemp>>'] = 'Egor'
 $npc_lastname['A<<npctemp>>'] = 'Klyuyev'
 $npc_usedname['A<<npctemp>>'] = 'Porn actor Egor Klyuyev'
 $npc_notes['A<<npctemp>>'] = 'In his early 50s, Egor is the oldest and most experienced actor at the porn studio. He''s living a dream life of being paid to fuck hot girls all day long, a fact he likes to proudly boast about to anyone who listens.'

+ 7 - 7
locations/npcstatic5.qsrc

@@ -72,7 +72,7 @@ $npc_dna['A<<npctemp>>'] = '7086114441 7277581517 7759004439 7806044180 78472404
 $npc_firstname['A<<npctemp>>'] = 'Rozalina'
 $npc_nickname['A<<npctemp>>'] = 'Roza'
 $npc_lastname['A<<npctemp>>'] = 'Harkov'
-$npc_usedname['A<<npctemp>>'] = 'Porn actress Scarlett Rose'
+$npc_usedname['A<<npctemp>>'] = 'Scarlett Rose'
 $npc_notes['A<<npctemp>>'] = 'Roza and her older brother Vasya are both in the porn business, "agreeing" to do it after she was raped for late repayment of her debt. She dropped out of university where she was learning to be a doctor to do porn, hoping to get the debt hunters off her back as soon as she can.'
 npc_dob['A<<npctemp>>'] = 19970202
 npc_gender['A<<npctemp>>'] = 1
@@ -686,11 +686,11 @@ npc_dick['A<<npctemp>>'] = 16
 
 npctemp = 234
 $npc_dna['A<<npctemp>>'] = '9695699672 2188071337 5246878581 9504515633 1030174716 8079090096 1524386291'
-$npc_firstname['A<<npctemp>>'] = 'Eleanor'
-$npc_nickname['A<<npctemp>>'] = 'Ellie'
-$npc_lastname['A<<npctemp>>'] = 'Bishop'
-$npc_usedname['A<<npctemp>>'] = 'Ellie Knight'
-$npc_notes['A<<npctemp>>'] = 'An American exchange student who does porn to pay her way through life. The fact that she''s American makes her unpopular with her co-stars, but she makes up for this by being good at her job.'
+$npc_firstname['A<<npctemp>>'] = 'Ashley'
+$npc_nickname['A<<npctemp>>'] = 'Ash'
+$npc_lastname['A<<npctemp>>'] = 'Wells'
+$npc_usedname['A<<npctemp>>'] = 'Ash Lee'
+$npc_notes['A<<npctemp>>'] = 'An American student on a gap year who is doing porn to fund her current lifestyle. She''s considered a ''forbidden fruit'' by her male co-stars, but is unpopular amongst the female stars.'
 npc_dob['A<<npctemp>>'] = 19961209
 npc_gender['A<<npctemp>>'] = 1
 
@@ -749,7 +749,7 @@ $npc_firstname['A<<npctemp>>'] = 'Aliana'
 $npc_nickname['A<<npctemp>>'] = 'Alli'
 $npc_lastname['A<<npctemp>>'] = 'Smirnova'
 $npc_usedname['A<<npctemp>>'] = 'Alli Smirnova'
-$npc_notes['A<<npctemp>>'] = 'A teen who is obsessed with porn. Against her parents wishes, she joined the studio on her 18th birthday and is always eager to get on camera. Her young age and attractive appearance gives her a lot of age play roles and makes her extremely popular with her male co-stars.'
+$npc_notes['A<<npctemp>>'] = 'A sex obessed teen who, against her parents wishes, went into porn instead of attending university. Always eager to get on camera, her young age and attractive appearance gives her a lot of age play roles and makes her extremely popular with her male co-stars.'
 npc_dob['A<<npctemp>>'] = 19980523
 npc_gender['A<<npctemp>>'] = 1
 

+ 14 - 14
locations/npcstatic6.qsrc

@@ -359,7 +359,7 @@ $npc_dna['A<<npctemp>>'] = '0'
 $npc_firstname['A<<npctemp>>'] = 'Mia'
 $npc_nickname['A<<npctemp>>'] = 'Mia'
 $npc_lastname['A<<npctemp>>'] = 'Radimova'
-$npc_notes['A<<npctemp>>'] = 'The elder of the identical twins studying nursing at the university. She and Yana are inseparable and are seen almost everywhere together. Like her younger sister, she enjoys playing pranks on her professors and classmates and causing confusion about who is actually who. Her parents are divorced, but her father pays for her tuition. There is a rumor spreading across campus claiming that he is a porn star.'
+$npc_notes['A<<npctemp>>'] = 'The elder of the identical twins studying nursing at the university. She and Yana are inseparable and are seen almost everywhere together. Like her younger sister, she enjoys playing pranks on her professors and classmates and causing confusion about who is actually who. Her parents are divorced, but her father pays for her tuition. There is a rumor spreading across campus claiming that he is a porn actor.'
 npc_dob['A<<npctemp>>'] = 19980325
 npc_gender['A<<npctemp>>'] = 1
 
@@ -379,7 +379,7 @@ $npc_dna['A<<npctemp>>'] = '0'
 $npc_firstname['A<<npctemp>>'] = 'Yana'
 $npc_nickname['A<<npctemp>>'] = 'Yana'
 $npc_lastname['A<<npctemp>>'] = 'Radimova'
-$npc_notes['A<<npctemp>>'] = 'The younger of the identical twins studying nursing at the university. She and Mia are inseparable and are seen almost everywhere together. Like her older sister, she enjoys playing pranks on her professors and classmates and causing confusion about who is actually who. Her parents are divorced, but her father pays for her tuition. There is a rumor spreading across campus claiming that he is a porn star.'
+$npc_notes['A<<npctemp>>'] = 'The younger of the identical twins studying nursing at the university. She and Mia are inseparable and are seen almost everywhere together. Like her older sister, she enjoys playing pranks on her professors and classmates and causing confusion about who is actually who. Her parents are divorced, but her father pays for her tuition. There is a rumor spreading across campus claiming that he is a porn actor.'
 npc_dob['A<<npctemp>>'] = 19980325
 npc_gender['A<<npctemp>>'] = 1
 
@@ -477,7 +477,7 @@ $npc_firstname['A<<npctemp>>'] = 'Rostislav'
 $npc_nickname['A<<npctemp>>'] = 'Rostislav'
 $npc_lastname['A<<npctemp>>'] = 'Popov'
 $npc_usedname['A<<npctemp>>'] = 'Rostislav'
-$npc_notes['A<<npctemp>>'] = 'Radomir''s father, he is a fit attractive man in his early forties. He has a attitude that women only exist to provide sexual pleasure to men and that no man should ever be tied to a single woman. He believe it is natural for men to cheat on their wives or girlfriends and has passed his view down to his two sons. He works at one of the factories in the city.'
+$npc_notes['A<<npctemp>>'] = 'Radomir''s father. A fit and attractive man in his early forties, he believes that women only exist to provide sexual pleasure to men and that no man should ever be tied to a single woman. He believes it is natural for men to cheat on their wives or girlfriends and has passed his views down to his two sons. He works at one of the factories in the city.'
 npc_dob['A<<npctemp>>'] = 19741225
 npc_gender['A<<npctemp>>'] = 0
 
@@ -498,7 +498,7 @@ $npc_firstname['A<<npctemp>>'] = 'Radislav'
 $npc_nickname['A<<npctemp>>'] = 'slava'
 $npc_lastname['A<<npctemp>>'] = 'Popov'
 $npc_usedname['A<<npctemp>>'] = 'Radislav'
-$npc_notes['A<<npctemp>>'] = 'Radomir''s older brother, he is a fit attractive young man in his early to mid twenties. When he attended Pavlovsk school he was the captain of the football team and the top athlete, he won several awards. Afterwards he went to the University where he screwed around and flunked out, after that he moved back home and got a job in the same factor as his father.'
+$npc_notes['A<<npctemp>>'] = 'Radomir''s older brother, a fit and attractive young man in his early twenties. He was the captain of the Pavlovsk school''s football team and the top athlete, for which he won several awards. Afterwards, he went to the university, but screwed around and flunked out. He then moved back home and got a job in the same factory as his father.'
 npc_dob['A<<npctemp>>'] = 19940303
 npc_gender['A<<npctemp>>'] = 0
 
@@ -522,7 +522,7 @@ $npc_firstname['A<<npctemp>>'] = 'Maya'
 $npc_nickname['A<<npctemp>>'] = 'Maya'
 $npc_lastname['A<<npctemp>>'] = 'Semionova'
 $npc_usedname['A<<npctemp>>'] = 'Maya'
-$npc_notes['A<<npctemp>>'] = 'Maya is the daughter of Anitchka a freelance coryphée, she was encouraged to dance from a young age until she was nine when she started doing gymnastics. This changed when she was eleven when her mother became ill and she was asked to carry on the family tradition. Maya is a naturally gifted dancer and after six years is tipped to become one of Russia''s leading stars in the future.'
+$npc_notes['A<<npctemp>>'] = 'Maya is the daughter of Anitchka. A freelance coryphée, she was encouraged to dance from a young age until she was nine, when she started doing gymnastics. This changed when she was eleven, when her mother became ill and she was asked to carry on the family tradition. Maya is a naturally gifted dancer and after six years is tipped to become one of Russia''s leading stars in the future.'
 npc_dob['A<<npctemp>>'] = 19990502
 npc_gender['A<<npctemp>>'] = 1
 npc_bust['A<<npctemp>>'] = 14
@@ -544,7 +544,7 @@ gs 'npcstaticdefaults', 'body', 'model'
 
 npctemp = 275
 !! Kima Agapova - The dance critic and fanatical to become a dancer, no matter the cost. Keeps a 'black book' of contacts and information. Arguably the best dancer in the school alongside Maya. She will try and gather information on Sveta's activities.
-!! will try and blackmail Sveta into either giving up if she learns if she's has dirty secrets such as prostitution, slut rep, etc or passing the information to Rudolph to destroy her career to remove her as competition.
+!! will try and blackmail Sveta into either giving up if she learns she has dirty secrets such as prostitution, slut rep, etc or passing the information to Rudolph to destroy her career and remove her as competition.
 $npc_firstname['A<<npctemp>>'] = 'Kima'
 $npc_nickname['A<<npctemp>>'] = 'Kima'
 $npc_lastname['A<<npctemp>>'] = 'Agapova'
@@ -565,7 +565,7 @@ gs 'npcstaticdefaults', 'skills', 'dance', 'sport'
 gs 'npcstaticdefaults', 'body', 'model'
 
 npctemp = 277
-!! Galina Molchalina - Quiet and shy student, age 16. Highly secretive and doesn't engage with the class, she also has a nervous personality as if she's afraid. This comes from her family being marked as 'radicals' by the old KGB and under constant watch from FSB even to this day.
+!! Galina Molchalina - Quiet and shy student, age 16. Highly secretive and doesn't engage with the class, she also has a nervous personality as if she's afraid. This comes from her family being marked as 'radicals' by the old KGB and under constant watch from FSB, even to this day.
 $npc_firstname['A<<npctemp>>'] = 'Galina'
 $npc_nickname['A<<npctemp>>'] = 'Galina'
 $npc_lastname['A<<npctemp>>'] = 'Molchalina'
@@ -575,8 +575,8 @@ gs 'npcstaticdefaults', 'skills', 'dance', 'sport'
 gs 'npcstaticdefaults', 'body', 'model'
 
 npctemp = 278
-!! Taisiya Lebedeva - The eldest student, and an elegant beauty, Age 18. A quiet, but captivating beauty who has a enchanting charismatic presence that men can't keep their eyes off her leading to bitchy remarks from other girls.
-!! She''s oblivous to her beauty instead focusing on acting and dance. (side note: surname is one of the most common in St P.), she's got a strong religous personality.
+!! Taisiya Lebedeva - The eldest student, and an elegant beauty, Age 18. A quiet, but captivating beauty who has an enchanting charismatic presence, men can't keep their eyes off her, leading to bitchy remarks from other girls.
+!! She''s oblivous to her beauty, instead focusing on acting and dance. (side note: surname is one of the most common in St P.), she's got a strong religous personality.
 !! Character model: Malta Aurelie
 $npc_firstname['A<<npctemp>>'] = 'Taisiya'
 $npc_nickname['A<<npctemp>>'] = 'Taisiya'
@@ -587,7 +587,7 @@ gs 'npcstaticdefaults', 'skills', 'dance', 'sport'
 gs 'npcstaticdefaults', 'body', 'model'
 
 npctemp = 279
-!! Nikita Volkova - Bronya''s daughter. Age 16. Keep fit fanatic, and does tap, ballet, etc. As Bronya's daughter she's been given privileged access to the school, whilst not a great talent she's still one of the best dance students at the school but just not at ballet despite Bronya's hopes.
+!! Nikita Volkova - Bronya''s daughter. Age 16. Keep fit fanatic, and does tap, ballet, etc. As Bronya's daughter, she's been given privileged access to the school. While not a great talent, she's still one of the best dance students at the school. Just not at ballet, despite Bronya's hopes.
 $npc_firstname['A<<npctemp>>'] = 'Nikita'
 $npc_nickname['A<<npctemp>>'] = 'Volkova'
 $npc_lastname['A<<npctemp>>'] = 'Volkova'
@@ -601,7 +601,7 @@ $npc_firstname['A<<npctemp>>'] = 'Gasha'
 $npc_nickname['A<<npctemp>>'] = 'Gasha'
 $npc_lastname['A<<npctemp>>'] = 'Morozova'
 $npc_usedname['A<<npctemp>>'] = 'Gasha'
-$npc_notes['A<<npctemp>>'] = 'The youngest in the class at 15, close friend of Nikita as the grew up in the same village. Nikita and Galina are often seen in each others company in the local coffee shop and rarely seen alone leading to rumours. She''s a bit of a foodie, and love sweet things which conflicts with keeping in shape for her dance career.'
+$npc_notes['A<<npctemp>>'] = 'The youngest in the class at 15 and a close friend of Nikita as they grew up in the same village. Nikita and Galina are often seen in each other''s company in the local coffee shop and are rarely seen alone, leading to rumours. She''s a bit of a foodie and love sweets things, which conflicts with keeping in shape for her dance career.'
 npc_dob['A<<npctemp>>'] = 20000705
 npc_gender['A<<npctemp>>'] = 1
 npc_bust['A<<npctemp>>'] = 9
@@ -618,7 +618,7 @@ gs 'npcstaticdefaults', 'skills', 'dance', 'sport'
 gs 'npcstaticdefaults', 'body', 'model'
 
 npctemp = 281
-!! Calina and Ruza Sokolova - Twin dancers. Not interested in ballet, but took the course to further their education into becoming dancers. Age 17. They also professional models with a Moscow agency.
+!! Calina and Ruza Sokolova - Twin dancers. Not interested in ballet, but took the course to further their education into becoming dancers. Age 17. They are also professional models with a Moscow agency.
 !! Adel and Alina Fakhteeva twins?
 $npc_firstname['A<<npctemp>>'] = 'Calina'
 $npc_nickname['A<<npctemp>>'] = 'Callie'
@@ -643,7 +643,7 @@ $npc_nickname['A<<npctemp>>'] = 'Rudolf '
 $npc_lastname['A<<npctemp>>'] = 'Baryshnikov'
 $npc_usedname['A<<npctemp>>'] = 'Rudolf'
 npc_dob['A<<npctemp>>'] = 19820920
-$npc_notes['A<<npctemp>>'] = 'Rudolf is a charming and handsome man, he was on course to become one of Russia''s best ballet dancers until a stage accident cut short his career. Today he works at the dance school as a instructor, agent and a board member. Many rumours about his life have swirled around him over the years but none have been proven.'
+$npc_notes['A<<npctemp>>'] = 'Rudolf is a charming and handsome man who was on course to become one of Russia''s best ballet dancers until a stage accident cut short his career. He now works at the dance school as an instructor, agent and a board member. Many rumours about his life have swirled around him over the years, but none have ever been proven.'
 npc_gender['A<<npctemp>>'] = 0
 gs 'npcstaticdefaults', 'defaults'
 $npc_thdick['A<<npctemp>>'] = 'slim'
@@ -669,7 +669,7 @@ $npc_nickname['A<<npctemp>>'] = 'Sofia'
 $npc_lastname['A<<npctemp>>'] = 'Solovyova'
 $npc_img_path['A<<npctemp>>'] = 'images/characters/ballet'
 gs 'npcstaticdefaults', 'defaults'
-!! Residential Warden: Bronya Volkova and former violinist, strict but fair has two daughters with Nikita being the youngest training to be a ballet dancer and her eldest in Germany training to be a surgeon.
+!! Residential Warden: Bronya Volkova and former violinist. Strict but fair. Has two daughters, with Nikita, the youngest, training to be a ballet dancer and her eldest in Germany training to be a surgeon.
 npctemp = 286
 $npc_firstname['A<<npctemp>>'] = 'Bronya'
 $npc_nickname['A<<npctemp>>'] = 'Bronya '

+ 1 - 2
locations/pirsingsalon.qsrc

@@ -1817,8 +1817,7 @@ if $ARGS[0] = 'tattoo_wrist':
 end
 
 if $ARGS[0] = 'tattoo_wrist2':
-	'<center><img src="<<func(''tattoo_management'', ''			*p '<a href="exec: gt ''pirsingsalon'', ''tattoo_wrist2'', <<ps_i>>"><img height="250" src="<<func(''tattoo_management'', ''wrist_image'', ps_i)>>"></a>'
-'', ARGS[1])>>"></center>'
+	'<center><img src="<<func(''tattoo_management'', ''wrist_image'', ARGS[1])>>"></center>'
 
 	if max(money, karta) < 7000:
 		'You cannot afford this tattoo.'

+ 9 - 9
locations/pornfilm.qsrc

@@ -42,13 +42,13 @@ if $ARGS[0] = 'pornactor':
 			if num < pfactor:
 				num2 = pfactor
 				:actorloop2
-					if $pactor[num] = $pactor[num2]:jump 'actorloop'
+					if $pactor[num] = $pactor[num2]: jump 'actorloop'
 					num2 -= 1
-				if num2 > num:jump 'actorloop2'
+				if num2 > num: jump 'actorloop2'
 			end
-			if aksex[akrand] = 0:aksex[akrand] = 1 & guy += 1
+			if aksex[akrand] = 0: aksex[akrand] = 1 & guy += 1
 			num -= 1
-		if num > 0:jump 'actorloop'
+		if num > 0: jump 'actorloop'
 	end
 end
 
@@ -61,7 +61,7 @@ if $ARGS[0] = 'pornactress':
 				$pactress[num] = 'Krystal'
 				$pactressID[num] = 'A207'
 			elseif akrand = 2:
-				$pactress[num] = 'Ellie Knight'
+				$pactress[num] = 'Ash Lee'
 				$pactressID[num] = 'A234'
 			elseif akrand = 3:
 				$pactress[num] = 'Juliana Slavenka'
@@ -79,13 +79,13 @@ if $ARGS[0] = 'pornactress':
 			if num < pfactor:
 				num2 = pfactor
 				:actressloop2
-					if $pactress[num] = $pactress[num2]:jump 'actressloop'
+					if $pactress[num] = $pactress[num2]: jump 'actressloop'
 					num2 -= 1
-				if num2 > num:jump 'actressloop2'
+				if num2 > num: jump 'actressloop2'
 			end
-			if aksex[akrand] = 0:aksex[akrand] = 1 & girl += 1
+			if aksex[akrand] = 0: aksex[akrand] = 1 & girl += 1
 			num -= 1
-		if num > 0:jump 'actressloop'
+		if num > 0: jump 'actressloop'
 	end
 end
 

+ 8 - 3
locations/wardrobe.qsrc

@@ -229,18 +229,19 @@ $default_clothing_line = {
 	!! ARGS 2 - clothing index
 
 	gs 'themes', 'clothing'
-	gs 'clothing_attributes', $defclothingtype[default_entry], defclothingnumber[default_entry]
 
 	$RESULT = '<TR bgcolor='+$temp_bcolor+'>'
 
 	$RESULT +='<TD><b><<$def_clothing_name[default_entry]>></b></TD>'
 
+	gs 'clothing_attributes', $defclothingtype[default_entry], defclothingnumber[default_entry]
 	if defclothingnumber[default_entry] = 0:
 		$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 	else
 		$RESULT +='<TD><img width="100" src="<<FUNC(''$clothing_image'', $defclothingtype[default_entry], defclothingnumber[default_entry])>>"></TD>'
 	end
 	if defunderwear[default_entry] = 2:
+		gs 'underwear_attributes', $defbodysuittype[default_entry]+'_bodysuits', defbodysuitnumber[default_entry]
 		if defbodysuitnumber[default_entry] = 0:
 			$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 		else
@@ -248,22 +249,26 @@ $default_clothing_line = {
 		end
 		$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 	else
+		gs 'underwear_attributes', $defbratype[default_entry]+'_bras', defbranumber[default_entry]
 		if defbranumber[default_entry] = 0:
 			$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 		else
 			$RESULT +='<TD><img width="100" src="<<FUNC(''$bra_image'', $defbratype[default_entry], defbranumber[default_entry])>>"></TD>'
 		end
+		gs 'underwear_attributes', $defpantytype[default_entry]+'_panties', defpantynumber[default_entry]
 		if defpantynumber[default_entry] = 0:
 			$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 		else
 			$RESULT +='<TD><img width="100" src="<<FUNC(''$panty_image'', $defpantytype[default_entry], defpantynumber[default_entry])>>"></TD>'
 		end
 	end
+	gs 'shoe_attributes', $defshoetype[default_entry], defshoenumber[default_entry]
 	if defshoenumber[default_entry] = 0:
 		$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 	else
 		$RESULT +='<TD><img width="100" src="<<FUNC(''$shoe_image'', $defshoetype[default_entry], defshoenumber[default_entry])>>"></TD>'
 	end
+	gs 'coat_attributes', $defcoattype[default_entry], defcoatnumber[default_entry]
 	if defcoatnumber[default_entry] = 0:
 		$RESULT +='<TD><img width="100" src="images/pc/items/blank.jpg"></TD>'
 	else
@@ -594,7 +599,7 @@ if $ARGS[0] = 'default_entry_wear':
 	end
 
 	!! default school girl uniform is always allowed to be worn if still in school
-	if mid($start_type,1,2) = 'sg' and SchoolAtestat = 0 and SchoolBlock = 0 and $temp1 = 'gm_school' and temp2 = 6:
+	if $start_type['loc'] = 'sg' and SchoolAtestat = 0 and SchoolBlock = 0 and $temp1 = 'gm_school' and temp2 = 6:
 		cla & *clr
 		'<center><video autoplay loop src="images/pc/activities/misc/dress_1.mp4"></video></center>'
 		'Your put on your <<$def_clothing_name[default_entry]>> outfit without any problems.'
@@ -649,7 +654,7 @@ if $ARGS[0] = 'default_entry_wear':
 			act 'Return': gt 'wardrobe', $wloc
 		end
 	!! not exercise clothing, and not loose fitting
-	elseif (CloStyle2 ! 6 and CloStyle ! 5) or $temp1 ! 'nude':
+	elseif CloStyle2 ! 6 and CloStyle ! 5 and $temp1 ! 'nude':
 		!! check for if the hipsize is too far from your hipsize
 		dynamic 'RESULT = <<$temp1>>_b[<<temp2>>]'
 		if RESULT < pcs_hips - 8 or RESULT > pcs_hips + 8:

+ 10 - 2
qsrc2tw/package-lock.json

@@ -5,6 +5,7 @@
   "packages": {
     "": {
       "dependencies": {
+        "@types/jqueryui": "^1.12.23",
         "gridstack": "^10.3.1"
       },
       "devDependencies": {
@@ -35,17 +36,24 @@
       "version": "3.5.30",
       "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.30.tgz",
       "integrity": "sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/sizzle": "*"
       }
     },
+    "node_modules/@types/jqueryui": {
+      "version": "1.12.23",
+      "resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.23.tgz",
+      "integrity": "sha512-pm1yVNVI29B9IGw41anCEzA5eR2r1pYc7flqD471ZT7B0yUXIY7YNe/zq7LGpihIGXNzWyG+Q4YQSzv2AF3fNA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/jquery": "*"
+      }
+    },
     "node_modules/@types/sizzle": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz",
       "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/twine-sugarcube": {

+ 1 - 0
qsrc2tw/package.json

@@ -7,6 +7,7 @@
   },
   "types": "twine-code/interfaces.d.ts",
   "dependencies": {
+    "@types/jqueryui": "^1.12.23",
     "gridstack": "^10.3.1"
   }
 }

+ 4 - 3
qsrc2tw/tools/QSRC2TW/index.js

@@ -9,7 +9,7 @@ import os from 'node:os';
 
 import { execSync } from 'node:child_process';
 
-const VERSION = 6;
+const VERSION = 8;
 const generatedFilesPrefix = '-generated';
 const resourcesFilesPrefix = '+resources';
 
@@ -17,7 +17,7 @@ const program = new Command();
 program
   .name('QSP TO Sugarcube')
   .description('CLI to Convert Quest Soft sourcecode to Twine Sugarcube')
-  .version('0.0.6')
+  .version('0.0.8')
   .option('-in, --input-file-path <path>','the path where the qsrc-files are')
   .option('-out, --output-file-path <path>','the path where the tw-files go')
   .option('-f, --single-file <path>','only converts the specified file')
@@ -126,7 +126,8 @@ fs.cpSync("./resources", resourcesPath, {recursive: true});
 
 
 const executionTime =  (new Date()).getTime() - startTime;
-console.log('ENDED CONVERSION'.padEnd(30,'.')+ ' '+executionTime+' ms'+` (${filePaths.length-failedFiles.length} of ${filePaths.length} successful)`);
+const executionTimeString = `${Math.floor(executionTime/3600000).toString().padStart(2,'0')}:${Math.floor(executionTime % 3600000 / 60000).toString().padStart(2,'0')}:${Math.floor(executionTime % 60000 /1000).toString().padStart(2,'0')}.${(executionTime % 1000).toString().padStart(4,'0')}`;
+console.log('ENDED CONVERSION'.padEnd(30,'.')+ ' '+executionTimeString+` (${filePaths.length-failedFiles.length} of ${filePaths.length} successful)`);
 
 //#region Versioning File
     const pathOfVersioningFile = path.join(outPath,generatedFilesPrefix,'version.js');

+ 5 - 0
qsrc2tw/tools/QSRC2TW/resources/QSP-functions/strpos.js

@@ -0,0 +1,5 @@
+setup.qsp_strpos = (s, search, ...additionalArgs) => {
+    if(additionalArgs[0])
+        throw new Error("setup.qsp_strpos with more than 2 arguments is not implemented.");
+    return s.indexOf(search)+1;
+}

+ 1 - 1
qsrc2tw/tools/QSRC2TW/resources/QSP-macros/GT.js

@@ -88,7 +88,7 @@ Macro.add('gt', {
 	skipArgs : false,
 	handler  : function () {
 		try{
-			setup.gt(...this.args);
+			setup.qsp_gt(...this.args);
 		}
 		catch (ex) {
 			return this.error('ERROR in gt-widget: ' + ex.message);

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
qsrc2tw/tools/QSRC2TW/resources/resources/Topbar.css


+ 8 - 0
qsrc2tw/tools/QSRC2TW/resources/resources/Topbar.tw

@@ -42,4 +42,12 @@
 			<<run UI.restart();>>
 		<</button>>
 	<</id>>
+
+	<<id 'buttonEditor'>>
+		<<button 'E'>>
+			<<set _returnArgs = $args ?? [QSP.$ARGS[0]]>>
+			<<set $editor={"passage":State.passage, "returnPassage":State.passage, "returnArgs": _returnArgs}>>
+			<<goto 'editor'>>
+		<</button>>
+	<</id>>
 </div>

+ 4 - 2
qsrc2tw/tools/QSRC2TW/src/visitor/QsrcVisitor.js

@@ -269,9 +269,11 @@ export default class QsrcVisitor extends qsrcParserVisitor{
     }
 
     visitNumberLiteralWithOptionalSign(ctx){
+        const numberText = ctx.NumberLiteral().getText();
+        const number = Number(numberText); //Catch the edge cases where a number is prefixed with 0
         if(ctx.MINUS())
-            return `-${ctx.NumberLiteral().getText()}`;
-        return ctx.NumberLiteral().getText();
+            return `-${number}`;
+        return `${number}`;
     }
 
 

+ 81 - 0
qsrc2tw/tools/QSRC2TW/src/wardrobeItems.js

@@ -0,0 +1,81 @@
+//Don't forget to add the d-flag to your regex! It's needed for the use of indices.
+function splitByRegex(text,regex, callback){
+	let result = [];
+
+	let regexResult;
+	let previousEndIndex;
+	let previousRegexResult;
+
+	while(regexResult = regex.exec(text))
+	{
+        let thisEndIndex = regexResult.indices[0][1];
+        let thisStartIndex = regexResult.indices[0][0];
+        if(previousEndIndex){
+            const previousCodeSegment = text.substring(previousEndIndex,thisStartIndex);
+			result.push(callback(previousRegexResult,previousCodeSegment));
+
+        }
+
+        previousRegexResult = regexResult;
+        previousEndIndex = thisEndIndex;
+	}
+
+
+	let thisStartIndex = text.length;
+	const previousCodeSegment = text.substring(previousEndIndex,thisStartIndex);
+	result.push(callback(previousRegexResult,previousCodeSegment));
+
+	return result;
+}
+
+function stripPrefixFromObjectKeys(obj, prefix){
+	return Object.fromEntries(Object.entries(obj).map(([key,val]) => {
+		if(key.startsWith(prefix) && key.length > prefix.length)
+			return [key.substring(prefix.length),val];
+		return [key,val];
+	}));
+}
+
+export default function wardrobeItems(code,options){
+	let firstLine = code.split("\n")[0];
+	let twCode = firstLine.replace("#","::")+`\n`;
+
+	const itemIdPrefix = firstLine.trim().replace("# $attributes_","");
+
+	let tsCode = "setup.wardrobeStatic ??= {};\n";
+
+	const propertyRegex = /^\s*(\w+)\s*=\s*(\d+)\s*$/gm;
+	const stringPropertyRegex = /^\s*\$(\w+)\s*=\s*('|")(.*?)\2\s*$/gm;
+
+	const itemData = splitByRegex(code, /(?:else)?if\s+args\[1\]\s*=\s*(\d+):/gmid,
+		(regexResult,code) => {
+			const itemId = `${itemIdPrefix}_${regexResult[1]}`;
+
+			let properties = {};
+			let propertyRegexResult;
+			while(propertyRegexResult = propertyRegex.exec(code))
+				properties[propertyRegexResult[1]] = Number(propertyRegexResult[2]);
+			while(propertyRegexResult = stringPropertyRegex.exec(code))
+				properties[propertyRegexResult[1]] = propertyRegexResult[3];
+
+			if(properties['CloQuality'])
+				properties = Object.assign({type:'clothes'},stripPrefixFromObjectKeys(properties,'Clo'));
+			else if(properties['ShoQuality'])
+				properties = Object.assign({type:'shoes'},stripPrefixFromObjectKeys(properties,'Sho'));
+			else if(properties['BraQuality'])
+				properties = Object.assign({type:'bra'},stripPrefixFromObjectKeys(properties,'Bra'));
+			else if(properties['PanQuality'])
+				properties = Object.assign({type:'bra'},stripPrefixFromObjectKeys(properties,'Pan'));
+			else if(properties['CoatQuality'])
+				properties = Object.assign({type:'coat'},stripPrefixFromObjectKeys(properties,'Coat'));
+
+			if(options.shop)
+				properties.shop = options.shop;
+
+			return `setup.wardrobeStatic['${itemId}'] = ${JSON.stringify(properties)}\n`
+
+		});
+	tsCode += itemData.join("");
+
+	return [twCode,tsCode];
+}

+ 22 - 9
qsrc2tw/tools/QSRC2TW/task_processor.js

@@ -7,6 +7,7 @@ import path from "path";
 import defaultProcess from "./src/defaultProcess.js";
 import npcInit from "./src/npcInit.js";
 import skillDefinitions from "./src/skillDefinitions.js";
+import wardrobeItems from "./src/wardrobeItems.js";
 
 
 
@@ -64,20 +65,32 @@ function convertFile(task){
 		//#endregion
 
 		var convertMode = "default";
-
-		if(qsp2twOptions.startsWith("!! QSRC2TW_module")){
+		var convertModeOptions = {};
+		/*if(qsp2twOptions.startsWith("!! QSRC2TW_module")){
 			convertMode = qsp2twOptions.trim().split(" ").toReversed()[0];
+		}*/
+		const modeLookupRegex = /\s*!!\s*QSRC2TW_module\s+(\w+)(\s+{[^}]+})?/;
+		let modeLookupResult;
+		try{
+			if(modeLookupResult = modeLookupRegex.exec(qsp2twOptions)){
+				convertMode = modeLookupResult[1];
+				if(modeLookupResult[2])
+					convertModeOptions = JSON.parse(modeLookupResult[2]);
+			}
+		}
+		catch(e){
+			console.log(e.toString());
 		}
-
 
 		/**
 		 * Return value is Array [TwineCode, TSCode]. TwineCode must not be null.
 		 */
-		var convertFunction = (code)=>[null,null];
+		var convertFunction = (code,options)=>[null,null];
 		switch (convertMode) {
-			case "default": convertFunction = (code) => [defaultProcess(code),null]; break;
-			case "npcInit": convertFunction = (code) => npcInit(code); break;
-			case "stat_sklattrib_lvlset": convertFunction = (code) => skillDefinitions(code); break;
+			case "default": convertFunction = (code,options) => [defaultProcess(code),null]; break;
+			case "npcInit": convertFunction = (code,options) => npcInit(code); break;
+			case "stat_sklattrib_lvlset": convertFunction = (code,options) => skillDefinitions(code); break;
+			case "wardrobeItems": convertFunction = (code,options) => wardrobeItems(code,options); break;
 			default:
 				console.warn("Unreckognized Convert Mode");
 				break;
@@ -93,7 +106,7 @@ function convertFile(task){
 			if(!options.verboseErrors)
 				console = {log:(...args)=>{}, debug: (...args)=>{},warn:(...args)=>{}, error: (...args)=>{}};
 			try{
-				[twineCodeRaw,tsCodeRaw] = convertFunction(data);
+				[twineCodeRaw,tsCodeRaw] = convertFunction(data,convertModeOptions);
 			}
 			catch(e){
 				throw e;
@@ -102,7 +115,7 @@ function convertFile(task){
 				console = defaultConsole;
 			}
 			if(!twineCodeRaw){
-				console.error("Twine Code must be generated by every converMode");
+				console.error("Twine Code must be generated by every convertMode");
 				return [2,"Invalid convertFunction"];
 			}else{
 				twineCode = twineCodeRaw.split('\n')

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
qsrc2tw/tools/tweeGo/storyFormats/sugarcube-2/format.js


+ 81 - 0
qsrc2tw/twine-code/editor/Editor.css

@@ -0,0 +1,81 @@
+#passages:has(> #passage-editor){
+	grid-column: 1 / -1;
+	grid-row: 2 / -1;
+	z-index: 10;
+	padding: 0;
+	position: relative;
+}
+
+#passage-editor{
+	position: absolute;
+	display: grid;
+	grid-template-rows: auto 1fr;
+	grid-template-columns: 1fr repeat(3, min-content);
+	width: 100%;
+	height: 100%;
+}
+
+#passage-editor #commonTasks div{
+	margin-bottom: 1em;
+}
+
+#passage-editor #commonTasks div:hover {
+	background: #ccc;
+}
+
+#editorToolbar {
+	grid-column: 1 / -1;
+}
+
+
+.collapsable>h2{
+	cursor: pointer;
+}
+
+.collapsable h3 {
+	margin: 1em 0 0 0;
+	display: inline-block;
+	min-width: 6vw;
+}
+
+.collapsable{
+	--transitionSpeed: 0.3s;
+	transition: var(--transitionSpeed);
+	width: 30vw;
+	width: calc(30vw - 1em);
+	padding: 0 1em;
+	overflow: auto;
+}
+
+.collapsable.collapsed{
+	width: 2rem;
+	padding: 0;
+}
+
+.collapsable.collapsed>*{
+	display: none;
+}
+
+.collapsable.collapsed > h2:first-of-type {
+	font-size: 1em;
+	writing-mode: vertical-rl;
+	margin: 0;
+	transition: var(--transitionSpeed);
+	display: block;
+}
+
+.diff{
+	font-size: 0.7em;
+}
+
+.diff p{
+	margin: 0;
+}
+
+.diff p.addition{
+	color: rgb(0, 160, 0);
+}
+
+.diff p.substraction {
+	color: rgb(160,0, 0);
+}

+ 15 - 0
qsrc2tw/twine-code/editor/Editor.js

@@ -0,0 +1,15 @@
+
+setup.startEditor = (domId, text) =>{
+	setup.externalCodePromise('ace').then(()=>{
+		const editor = ace.edit(domId);
+		editor.setOption("showInvisibles", true);
+		editor.setTheme("ace/theme/chrome");
+		editor.session.setMode("ace/mode/html");
+		editor.session.setUseWorker(false);
+		editor.setValue(text);
+
+		setup.editor = editor;
+	});
+
+
+}

+ 121 - 0
qsrc2tw/twine-code/editor/Editor.tw

@@ -0,0 +1,121 @@
+:: editor
+
+<<set _changedFiles = JSON.parse(localStorage.getItem("SweetCube.Modifications") ?? '{}')>>
+
+<div id="editorToolbar">
+	<<=$editor.passage>>
+
+	<<button 'Save'>>
+		<<run setup.editorSave($editor.passage,setup.editor.getValue())>>
+	<</button>>
+	<<button 'Return'>>
+		<<gt $editor.returnPassage $editor.returnArgs[0]>>
+	<</button>>
+
+	<<set _allPassageNames = Story.lookupWith((p)=>true).map((p)=>p.title)>>
+	<<autocomplete "_openPassageName" _allPassageNames>>
+		<<set $editor.passage = _openPassageName>>
+		<<goto 'editor'>>
+	<</autocomplete>>
+</div>
+
+<div id="editor">
+
+</div>
+
+<div id="commonTasks" class="collapsable collapsed">
+	<h2>Common Tasks</h2>
+	<div class="comment">
+		This is an example of help that could be provided here.
+	</div>
+	<h3>Passage Links</h3>
+	<h4>Goto</h4>
+	<div>
+		You use a goto-command to get from one passage to another.
+		Each goto-command creates a new entry in the history.
+		The player can navigate between these steps using the arrow-buttons in the Topbar (if this isn't disabled).
+		This system breaks if goto-commands are chained.
+		<b>You should therefore avoid executing a goto-commands without user-input!</b>
+	</div>
+	<div>
+		<code>&lt;&lt;goto 'passage2'&gt;&gt;</code><br/>
+		This is the SugarCube-native way to execute a goto-command. Use it if no arguments have to be sent to the next passage.
+	</div>
+	<div>
+		<code>&lt;&lt;gt 'passage2' 'arg0' 'arg1'&gt;&gt;</code><br/>
+		This command behaves as it does in QSP: send the user to a passage and set some arguments for the receiving passage.
+		Not that the <b>arguments are not separated by commas</b>.
+	</div>
+	<div>
+		<code>&lt;&lt;run setup.qsp_gt('passage2' , 'arg0' , 'arg1')&gt;&gt;</code><br/>
+		This is the syntax you'll find in the auto-translated files.
+		It provides support for some weird edge cases (mostly concerning dynamic code).
+		If you don't need that, use one of the two previous approaches.
+	</div>
+</div>
+
+<div id="passageLinks" class="collapsable collapsed">
+	<h2>Passage Links</h2>
+	<<set _passageLinks = setup.getPassageLinks($editor.passage)>>
+
+	<<for _passageId, _passageLinkArray range _passageLinks>>
+		<<capture _passageId>>
+		<div>
+			<<link _passageId>>
+				<<set $editor.passage = _passageId>>
+				<<goto 'editor'>>
+			<</link>>: <<=_passageLinkArray.length>>x
+		</div>
+		<</capture>>
+	<</for>>
+
+	<h2>Links to this passage</h2>
+	<<set _passageLinksToCurrentPassage = setup.getPassageLinksToPassage($editor.passage)>>
+	<<for _passageId range _passageLinksToCurrentPassage>>
+		<<capture _passageId>>
+		<div>
+			<<link _passageId>>
+				<<set $editor.passage = _passageId>>
+				<<goto 'editor'>>
+			<</link>>
+		</div>
+		<</capture>>
+	<</for>>
+
+	<div class="comment">
+		These lists might be incomplete. Some connections can not be detected automatically or it isn't efficient to do so.
+	</div>
+</div>
+
+<div id="changedFiles" class="collapsable collapsed">
+	<h2>Changed Files</h2>
+	<div class="changedPassages">
+		<<for _passage, _changes range _changedFiles>>
+			<<set _diffId = "diff_"+_passage>>
+			<<capture _passage _changes _diffId>>
+				<div class="changedPassage">
+					<h3 class="passageName">_passage</h3>
+					<<link "Open">>
+						<<set $editor.passage=_passage>>
+						<<goto 'editor'>>
+					<</link>>
+					<<linkreplace "Diff">>
+						<<run setup.placeDiffInDom(_passage,window.SweetCube.originalPassageContents[_passage],_changes,"#"+_diffId)>>
+					<</linkreplace>>
+					<<link "Delete">>
+						<<run delete _changedFiles[_passage]>>
+						<<run localStorage.setItem("SweetCube.Modifications",JSON.stringify(_changedFiles))>>
+						<<run location.reload()>>
+					<</link>>
+					<code @id=_diffId class="diff"></code>
+				</div>
+			<</capture>>
+		<</for>>
+	</div>
+</div>
+
+<<done>>
+	<<run setup.startEditor('editor',Story.get($editor.passage).text)>>
+	<<run $(".collapsable > h2:first-of-type").on("click",function() {$(this).parent('.collapsable').toggleClass('collapsed');})>>
+<</done>>
+

+ 35 - 0
qsrc2tw/twine-code/editor/diff.js

@@ -0,0 +1,35 @@
+setup.placeDiffInDom = (title, oldContent, newContent, domSelector) => {
+	setup.externalCodePromise('diff').then(()=>{
+
+		const escapedChars = {
+			/*'&' : '&amp;',
+			'<' : '&lt;',
+			'>' : '&gt;',*/
+			'"' : '&quot;',
+			"'" : '&#39;',
+			'`' : '&#96;'
+		};
+
+		for(const [toBeEscaped, asEscaped] of Object.entries(escapedChars))
+        	oldContent = oldContent.replaceAll(toBeEscaped,asEscaped);
+
+		const unifiedDiffPatch = window.Diff.createTwoFilesPatch(title,title,oldContent,newContent,undefined,undefined,{ignoreWhitespace: true, stripTrailingCr: true});
+
+		let resultingHTML = "";
+
+		unifiedDiffPatch.split('\n').forEach((line)=>{
+			if(line.startsWith('@@')){
+				resultingHTML += `<p>${line}</p>`;
+			}else if(line.startsWith('---')){
+			}else if(line.startsWith('+++')){
+			}else if(line.startsWith('-')){
+				resultingHTML += `<p class="substraction">${line}</p>`;
+			}else if(line.startsWith('+')){
+				resultingHTML += `<p class="addition">${line}</p>`;
+			}
+
+		});
+
+		$(domSelector).html(resultingHTML);
+	});
+}

+ 30 - 0
qsrc2tw/twine-code/editor/save.js

@@ -0,0 +1,30 @@
+
+setup.editorSave = (passage,newContent) => {
+    const escapedChars = {
+        '&' : '&amp;',
+		'<' : '&lt;',
+		'>' : '&gt;',
+		'"' : '&quot;',
+		"'" : '&#39;',
+		'`' : '&#96;'
+    };
+
+    let sanitizedNewContent = newContent;
+
+    for(const [toBeEscaped, asEscaped] of Object.entries(escapedChars))
+        sanitizedNewContent = sanitizedNewContent.replaceAll(toBeEscaped,asEscaped);
+
+
+    const localStorageModsKey = "SweetCube.Modifications";
+
+    const updateObject = {};
+    updateObject[passage] = sanitizedNewContent;
+
+    const currentModificationsString = localStorage.getItem(localStorageModsKey) ?? "{}";
+    const currentModifications = JSON.parse(currentModificationsString);
+    const newModifications = Object.assign({},currentModifications,updateObject);
+    const newModificationsString = JSON.stringify(newModifications);
+    localStorage.setItem(localStorageModsKey, newModificationsString);
+
+    location.reload();
+}

+ 14 - 0
qsrc2tw/twine-code/external/_external.ts

@@ -0,0 +1,14 @@
+setup.externalCodeURLs ??= {};
+setup.externalCodePromises ??= {};
+
+setup.externalCodePromise = (promiseID: string)=>{
+	if(!setup.externalCodeURLs[promiseID])
+		return Promise.resolve();
+	setup.externalCodePromises[promiseID] ??= Promise.all(
+		[
+			importScripts(setup.externalCodeURLs[promiseID].code as unknown as string), // Casting to unknown because of a weird bug in the types
+			importStyles(...setup.externalCodeURLs[promiseID].style),
+		]
+	);
+	return setup.externalCodePromises[promiseID];
+}

+ 8 - 0
qsrc2tw/twine-code/external/ace.ts

@@ -0,0 +1,8 @@
+/// <reference path="./_external.ts" />
+setup.externalCodeURLs.ace = {
+    code: [
+        "https://cdn.jsdelivr.net/npm/[email protected]/src-min-noconflict/ace.js",
+        "https://cdn.jsdelivr.net/npm/[email protected]/src-min-noconflict/theme-chrome.min.js",
+    ],
+    style:["https://cdn.jsdelivr.net/npm/[email protected]/css/ace.min.css"],
+};

+ 5 - 0
qsrc2tw/twine-code/external/diff.ts

@@ -0,0 +1,5 @@
+/// <reference path="./_external.ts" />
+setup.externalCodeURLs.diff = {
+    code: ["https://cdn.jsdelivr.net/npm/[email protected]/dist/diff.min.js"],
+    style:[],
+};

+ 5 - 0
qsrc2tw/twine-code/external/jQueryUI.ts

@@ -0,0 +1,5 @@
+/// <reference path="./_external.ts" />
+setup.externalCodeURLs.jQueryUI = {
+    code: ["https://code.jquery.com/ui/1.14.0/jquery-ui.min.js"],
+    style:["https://code.jquery.com/ui/1.14.0/themes/base/jquery-ui.css"],
+};

+ 40 - 0
qsrc2tw/twine-code/misc/getPassageLinks.ts

@@ -0,0 +1,40 @@
+const passageLinkMarkups:{[key:string]:{type:string, regex: RegExp}} = {
+	'gs-macro': 	{type: 'gs',	regex: /<<gs\s+`\['([^']+)'[^\]]*\]`\s*>>/gd},
+	'gt-function':	{type: 'gt',	regex: /setup\.qsp_gt\('([^']+)'[^\)]*\s*\)/gd},
+
+	'goto':			{type: 'gt',	regex: /<<goto\s+'([^']+)'\s*>>/gd},
+	'include':		{type: 'gs',	regex: /<<include\s+'([^']+)'\s*>>/gd},
+};
+
+setup.getPassageLinks = function(passageId:string){
+	let result:{[passageId: string]: {type: string;line: number;}[];} = {};
+
+	const passageCode = Story.get(passageId).text;
+
+	for(const[key, markupSettings] of Object.entries(passageLinkMarkups)){
+		const regex = markupSettings.regex;
+		let regexMatch;
+		while(regexMatch = regex.exec(passageCode)) {
+			const passageId = regexMatch[1];
+			result[passageId] ??= [];
+			result[passageId].push({line:-1, type: markupSettings.type});
+		}
+	}
+
+	return result;
+}
+
+setup.getPassageLinksToPassage = function(passageId:string){
+	function anyPassageLinkMarkupMatches(text:string):boolean{
+		for(const[key, markupSettings] of Object.entries(passageLinkMarkups)){
+			let regexMatch;
+			while(regexMatch = markupSettings.regex.exec(text))
+				if(regexMatch[1] == passageId)
+					return true;
+		}
+		return false;
+	}
+
+	return Story.lookupWith(function(p){return anyPassageLinkMarkupMatches(p.text)}).map((passage)=>passage.title);
+
+}

+ 30 - 0
qsrc2tw/twine-code/misc/head.txt

@@ -1 +1,31 @@
 <meta name="rating" content="adult" />
+<script>
+	window.SweetCube ??= {passageInitOverwrites:[], originalPassageContents:{}};
+
+    function applyModifications(modifications={}){
+		function applyModification(passage, modification){
+			passage.element.innerHTML = modification;
+			return passage;
+		}
+
+
+		window.SweetCube.passageInitOverwrites.push((pid,passage)=>{
+			const passageName = passage?.element?.attributes?.name?.value;
+			if(!passageName || !modifications[passageName])
+				return passage;
+
+			window.SweetCube.originalPassageContents[passageName] = passage.element.innerHTML;
+
+			const modification = modifications[passageName];
+
+			return applyModification(passage,modification);
+		});
+    }
+
+	const modificationsString = localStorage.getItem("SweetCube.Modifications");
+	if(modificationsString){
+		const modifications = JSON.parse(modificationsString);
+		applyModifications(modifications);
+	}
+
+</script>

+ 1 - 1
qsrc2tw/twine-code/start/begin.tw

@@ -15,7 +15,7 @@
 	<<SHOWSTAT 1>>
 	<h2>CHOOSE GAME START</h2>
 	<div id="beginScenarioSelection" style="display: flex;justify-content: center;">
-		<<gs `['beginScenarioSelection']`>>
+		<<gs `['beginscenarioselection']`>>
 	</div>
 	<p>
 		There are three main start types:

+ 10 - 0
qsrc2tw/twine-code/twine-code.d.ts

@@ -63,6 +63,16 @@ declare module "twine-sugarcube" {
 
         qsp_dyneval: (code:string, ...args : (string|number)[]) => string|number;
         qsp_func: (passage:string,...arguments:(string|number)[]) => string|number;
+
+
+        //#region External Code
+            externalCodeURLs: {[key:string]:{code:string[],style:string[]}};
+            externalCodePromises: {[key:string]:Promise<any>};
+            externalCodePromise: (promiseId:string)=>Promise<any>;
+        //#endregion
+
+        getPassageLinks: (passageId:string) => {[passageId:string]:{type:string;line:number}[]};
+        getPassageLinksToPassage: (passageId:string) => string[];
     }
 
     export interface SugarCubeStoryVariables{

+ 36 - 0
qsrc2tw/twine-code/ui/autoComplete.ts

@@ -0,0 +1,36 @@
+Macro.add('autocomplete', {
+	skipArgs : false,
+    tags: [],
+	handler  : function () {
+		try{
+
+            const varname = this.args[0];
+            const domID = `autoComplete_${varname.replaceAll("$","--")}`;
+            const tags = this.args[1];
+
+            const innerCode = this.payload[0].contents;
+
+            $(this.output).wiki(`<<id '${domID}'>><<textbox "${varname}" "">><</id>>`);
+
+            $(document).one(':passagedisplay', function (ev) {
+                setup.externalCodePromise('jQueryUI').then(function () {
+                    $(`#${domID}`).autocomplete({
+                        source: tags,
+                        select: (event, ui) => {
+                            const v = ui.item.value;
+                            State.setVar(varname,v);
+                            $.wiki(innerCode);
+                        }
+                    });
+
+                });
+            });
+		}
+		catch (ex) {
+			return this.error('ERROR in gt-widget: ' + ex.message);
+		}
+	}
+});
+
+
+

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio