New event commands

	/cg <cgName>/
	/cg someCG/
	
	
Shows an image on the screen. Image stretches to fill screen, even when game window is resized.

CG images must be loaded through Content Patcher. 
Target must begin with CG/
For example, this Content Patcher patch:

 	{
		"Action": "Load",
        "Target": "CG/someCG", 
        "FromFile": "assets/CGs/someCG.png",
    },

should be shown with this event command:
	/cg someCG/




	/vn <cgName> [fade?] [fadeSeconds]/
	/vn someCG/
	/vn someCG fade/
	/vn someCG fade 2.5/

Similar as /cg/ but enables a minimal dialogue theme similar to that of a visual novel.

	/vn cgName fade 1.5/
	/cg cgName fade 1.5/
	
The optional fade [seconds] parameter sets the time to spend fading the next cg image in.


	/setCgFade 1.5/

Sets the default fade time for the rest of the cgs in the event, or until it's changed with this command again.

	

	/cgAnimate (cg frames separated by spaces) (optional flags)/
	/cgAnimate (cg1 cg2 cg3)/
	/cgAnimate (cg1 cg2 cg3) time 1000 loops 10 wait/

Shows an animation of CGs.
Possible flags:

	time <timeMS>				Time between frames										Default 1000 (10 fps)
	loops <numberOfLoops>		Number of loops. 0/1 = show each frame once.			Default -1 (infinite loops)
	wait						If set, event pauses until animation is done.
	transparent					If set, enables transparency.
	scale <scale>				Changes size of the CGs.								Default 1.




	/cgClear/
	
Clears the cg on the screen and removes VN theming if it's enabled. Clears animation.








	/var varName varValue/
	
Creates or edits a variable.
Variables can be text or numbers.
Variables get cleared on event end.
Variables can be used for:
	-if statements
	-event commands and args
	-anything, and anywhere (in events)

You can use variables, classes, and arrays in any command:
	
	/var character HatKid/move $character 10 0 0/
	/class someClass (character=HatKid;moveArgs=10 0 0)/move $someClass.character $someClass.moveArgs/
	/array someArray (move HatKid 10 0 0;speak HatKid \"Hello!\";jump HatKid 8)/$$someArray/			//This will select a random entry of the array








	/class className (name=Nobeta;hp=100;damage=25;speed=5;greeting=Hi! How are you?)/
	/class newClass oldClass/
	/var className.varName varValue/
	
Creates or copies a class.
Any amount and type of variables work.

Examples:
	/if $someClass.someVariable == 10 switchEvent 123_abc/
	/add someClass.someVariable 10/
	/speak $someClass.name \"$someClass.message\"/
	






	
	/array arrayName (string1;string2;string3;string4...)/
	/array newArray oldArray/
	/arrayAdd arrayName newValue/
	/arrayRemove arrayName newValue/
	/arrayVar varName arrayName/
	/arraySep <separator>/

Creates a new array. (Actually a list)
Arrays can be pasted in their entirety with $arrayName, example:

	/array someArray (value1;value2;value3;value4)/arraySep _/	
	now		/speak HatKid \"$someArray\"/	will turn into		/speak HatKid \"value1_value2_value3_value4\"/

	/array someArray (value1;value2;value3;value4)/arraySep ,/	
	now		/speak HatKid \"$someArray\"/	will turn into		/speak HatKid \"value1,value2,value3,value4\"/


Arrays can be used to get a random variable with $$arrayName, example:

	/array nameList (Jas;Renata;HatKid;Nobeta)/
	/array messageList (Hi there, How are you?;Nice day, isn't it?;I am going to the beach today.)
	/array forkList (123_abc;123_xyz)/
	/array jumpHeights (2;4;6;8)/

	/ifChar Morgan arrayAdd nameList Morgan/

	/switchEvent $$forkList/
	/speak $$nameList \"$$messageList\"/
	/jump $$nameList $$jumpHeights/















	/add varName 10/
	/add varName -10.55/

Adds (or removes if negative) the value from the variable's value if the variable is a number.










	/append <varName> <text>/
	/append speech Great, isn't it?/
	/append speech #$b#I am doing great, by the way!/
	
Adds text to the end of a variable.
Useful for speech variables. Example:
/var speech Hello, how are you?/if $doingGood == true append speech #$b#I am doing great, by the way!$h/
/speak Renata \"$speech\"/









	/sum <varName> <vars or numbers...>
	/sum varName $var1 103 12.5 1130.1 $var2/

Creates or edits a variable, with the value being the sum of the numbers. Non-numbers get ignored.








	/print some text goes here/
	/print $someVariable/
	/printClass className/

Shows a message in console, for example a variable.
Requires the developer version of SMAPI to be seen.
Aliases with respective error levels:

	print
	printDebug
	printInfo
	printWarn
	printAlert
	printError

	 
Printclass shows a class' values, or "null" if it does not exist.

	/printClass someClass/







	/if (conditions) (command)
	/if (conditions) {commands separated by ;}
	/if $varName == helloabc switchEvent 123_abc/		
	/if $varName < 100 switchEvent 123_abc/
	/if $varName == $otherVarName switchEvent 123_abc/
	/if [Season] == winter speak Renata \"It's winter!\"/
	/if $varName == 100 && $varname2 == 100 {command1;command2;command3;command4;command5;etc...}/
	/if $varName == null {commandsIfNull}
	
Checks condition(s), then executes the command(s) after.
You must prefix a variable name with $ to differentiate it from a static value.
After the if statement, almost all event commands work, but switchEvent is recommended for readability and simplicity.
You can use [Tokens].
You can check if a variable exists or doesn't with 		/if $varName == null {commands if varibale doesn't exist}/		/if $varName != null {commands if variable exists}/
You can set variables to null with		/var someVar null/

Operators:
	==
	!=
	>
	>=
	<
	<=

You can use && (and) and || (or) to create multiple conditions in one statement, example:
	/if $someVar == 100 && $anotherVar == 50 && $yetAnotherVar == 25 switchEvent 123_abc/		// "&&" means all conditions must be true.
	/if $someVar == 100 || $anotherVar == 50 || $yetAnotherVar == 25 switchEvent 123_abc/		// "||" means at least one of the conditions must be true.




Note when using brackets for multiple commands after if: 
Because all variables are converted when the if command is first read, even the commands in the brackets,
any bracket commands with variables in them might have outdated data if they get changed before the command is reached.
Consider using switching to a fork instead.

Errorprone:
	/if $someVar == abc {var someVar xyz;var someOtherVar $someVar; switchEvent 123_abc}/
	//In this case someOtherVar will be abc even though the first bracket command sets it to xyz because the $someVar gets turned into abc the moment the entire command is read.


Good:
	/if $someVar == abc switchEvent 123_conditionMet/
	"123_condition_met":	"var someVar xyz/var someOtherVar $someVar/switchEvent 123_abc",







	/else (commands)/
	/else switchEvent 123_abc/
	/else {cmd1;cmd2;cmd3}/

Executes commands if last if command was false, else does nothing.





	/ifClass className (commands)/
	/ifClassNull className (commands)/

Check if a class exists OR is null, then executes the commands.






	/ifChar Ashley switchEvent 123_abc/
	/ifChar !Ashley switchEvent 123_abc/
	/ifChar Ashley switchEvent {command1;command2;etc}/

Checks if a character exists, then executes the command.
Useful to check if a mod is loaded. 
Can be inverted by prefixing character name with !. 
Inversion is useful to skip part of an event if a character doesn't exist.











	/ifItem <itemId> [numberOfItems=1] (commands if true)/
	/ifItem 232 switchEvent 123_abc/
	/ifItem 232 99 switchEvent 123_abc/
	/ifItem (F)232 99 switchEvent 123_abc/
	/ifItem (F)232 99 {command1;command2;command3;etc}/
	
Checks if player has items in inventory, then executes the command. 
If item type is not specific, defaults to (O)Objects
Item types
(O) 	Objects	(Most common items)
(T)		Tools
(W) 	Weapons
(B) 	Boots
(H) 	Hats
(S) 	Shirts
(P) 	Pants
(BC) 	Big Craftables
(F) 	Furniture
(FL) 	Flooring
(WP)	Wallpaper








	/ifMod <modId> <eventCommandsIfTrue>/
	/ifMod recettearmod switchEvent 123_abc/
	/ifMod recettearmod switchEvent {command1;command2;command3;etc}/

Checks if a mod is loaded, then executes the command.
<modId> is in the mod's manifest.json.








	/ifFlag ccVault switchEvent 123_abc/
	/ifFlag ccVault switchEvent {command1;command2;command3;etc}/

Checks if a mail flag is set, then executes the command. https://stardewvalleywiki.com/Modding:Mail_data
Mail flags do not necessarily need to have a readable mail, things like ccBus are also mail flags.








	/gsq #Season == WINTER#switchEvent 123_abc/

Checks if a GameStateQuery is true, then execute the command after the #.
https://stardewvalleywiki.com/Modding:Game_state_queries








	/func 123_abc [loops=1]/
	/func 123_abc/
	/func 123_abc 15/
	
Calls a sub-event/fork like a function, continuing back where it got called when it's done.
[loops] decides how many times to repeat.
Can use (i) token in the fork.


(i) example:
	
	"123_someFunc":		"warp HatKid (i) 0/pause 25",
	"123_ourEvent":		"func 123_someFunc 100/speak HatKid \"Okay I am off-screen now!\"/




	/for <iterations> (commands)/
	/for 10 {cmd1;cmd2;cmd3;cmd4...}

Repeats the commands a set amount of item.
Can use a (i) token. Make sure you use (round) brackets instead of vanilla [square]  brackets.

(i) example:

	/for 100 {positionsOffset HatKid (i) 0}/







	/foreach <arrayName> (commands)/
	/foreach characterList {pause 1000;warp (item) -100 -100}

Repeats the commands for every entry of an array.
Can use (i) and (item) token. Make sure you use (round) brackets instead of vanilla [square]  brackets.


(item) example:

	/foreach characterList {pause 1000;warp (item) -100 -100}

(i) example:

	/foreach characterList {positionsOffset (item) (i) 0}/







	/dynamicQuestion/
	/dynamicQuestion [QuestionText=""]/
	
	/clearDynamicQuestion/
	
	/addAnswer <answer> <fork>/
	/addAnswer <answer> <command>/
	/addAnswer <answer> {command1;command2;command3;etc}/
	/addAnswer \"Answer goes here\" 123_abc/
	/addAnswer \"Answer goes here\" speak Renata \"Yippee hooray!\"/
 	/addAnswer \"Answer goes here\" {command1;command2;command3;command4...}/

Dynamic questions are like quickQuestions, but all available answers can be determined by if statements.
For example:
/clearDynamicQuestion/addAnswer \"I am doing good.\" 123123_answer_doingGood/addAnswer \"I am doing bad.\" 123123_answer_doingBad/if $foundDiamond == true addAnswer \"I found a diamond!\" 123123_answer_foundDiamond/dynamicQuestion How are you doing?/	
	
In the above event, there's 2 answers that are always available, and a 3rd answer that is only conditionally available.	
The first variable of addAnswer is the button's text, the second variable is the fork/sub-event to switch to when that answer is chosen.

Make sure to start a line with clearDynamicQuestion so there are no left-over answers from previous questions.

If the last arg is a fork, the command will be a switchEvent, example:
	
	/addAnswer \"That's nice.\" 123_abc/		












	/endTeleport Forest 25 50/
	/endTeleport Forest 25 50 3/

Ends the event and teleports to the location and position.
Optional argument "3" is facing direction. 0/1/2/3 = up/right/down/left






	
	/switchRandomEvent/
	/switchRandomEvent [any number of forks]/
	/switchRandomEvent 123_abc1 123_abc2 123_abc3 123_abc4/
	
Switches to one of the random event forks in the list.
if [any number of forks] is included, ignores the list and chooses one from the argument.




	/addRandomEvent <fork> [weight=100]/
	/addRandomEvent 123_abc1/
	/addRandomEvent 123_abc2 50/					//This one is half as likely to happen as others.
	/ifChar Morgan addRandomEvent 123_morgan 100/

Adds a random event to the switchRandomEvent list. Useful with if statements.
[weight] determines likelyhood of event being picked relative to others. Default 100.



	/clearRandomEvent/
	
Clears the random event list.








	/setGotoEvent <forkAlias> <fork>/
	/setGotoEvent someContinueEvent 123123_abc/
	/gotoEvent <forkAlias>/
	/gotoEvent someContinueEvent/
	
Set an event to switch to later on.
Example:

"123_start":			"setGotoEvent afterEvent 123_continue1/switchEvent 123_someOtherFork",
"123_someOtherFork": 	"do/Stuff/Here/gotoEvent afterEvent",
"123_continue1":		"it goes to here",







	/viewportMoveTo <x> <y> <timeMS> [waitUntilDone=false]/
	/viewportMoveTo 37 42 2500/
	/viewportMoveTo 37 42 2500 true/

Moves viewport to tile position over time.
Event continues as normal, unless [waitUntilDone] is true.








	/speakRandom <characterName> (any number of messages seperated by ; without quotes)
	/speakRandom Nobeta Hi there how are you doing?$h;Hi, it's a nice day isn't it?$h;I am doing to take a little stroll.$h/

Calls the speak command with a random message, which are seperated by ;
Consider using speak Character \"$$array\"















	/animateName <characterName> <animationName> [flip=false] [loop=true] [timeBetweenFramesMS=100]
	/animateName HatKid hatKid_sandwich/
	/animateName HatKid hatKid_sandwich true true 25/

Animates a character with an animation from the animationDescriptions file.






























Puppetry!

	/Puppet <name> <source> <x> <y> <spriteWidth> <spriteHeight> <scale> [startingFrame = 0]/
	/Puppet Sue Sue -0.5 0.75 16 32 2/
	/Puppet Sue Sue -0.5 0.75 16 32 2 13/
	/Puppet Jas Portraits\\Jas -0.5 0.75 64 64 2/
	/Puppet ChocolateCake 220 -0.5 0.75 64 64 2/
	
Creates a puppet that can be moved around and animated. Coordinates in screen-space. (-1 to 1) When resizing the screen, the puppets' positions and size will update accordingly.

<source> can be:
-A spritesheet loaded through content patcher to the "Puppets/x" path.
-Any texture in the game like 	Portraits\\Jas
-An item ID like 220 or (O)220 for a chocolate cake.

<x> and <y>, -1 is the left or top, 0 is the center, and 1 is the right or bottom.
Puppets appear in front of CGs. Newer puppets appear in front of older puppets.
Content Patcher example:

	{
          "Action": "Load",
          "Target": "Puppets/Sue",  
          "FromFile": "assets/Puppets/Sue.png",
    },
	
	
	
	
	/PuppetPosition <name> <x> <y> [time]/
	/PuppetPosition Sue 0.2 -0.7/
	/PuppetPosition Sue 1 0.2 500/

Instantly moves puppet to target position.
If optional [time] is set, move puppet to target position in specified time in milliseconds (1000 per second).	




	/PuppetRotateTo <name> <degrees> [time]/
	/PuppetRotateTo Sue 90/
	/PuppetRotateTo Sue 270 500/

Instantly rotates puppet to target angle in degrees.
If optional [time] is set, rotate puppet to target angle in specified time in milliseconds (1000 per second).	




	/PuppetFrame <name> <frame>/
	/PuppetFrame Sue 1/

Sets the puppet's frame.
The frame's graphic depends on the puppet's sprite size.	
	
	
	
	
	/PuppetDefineAnimation <animationName> <any number of frames>/					
	/PuppetDefineAnimation Dance 0 1 2 4 2 2 3 1 3 0 0 2 3 10 23 24 10/
	/PuppetDefineAnimation Laugh 12 14/

Define an animation, to be used with PuppetAnimate.
The frames' graphics depend on the puppet's sprite size. Only use horizontal animations on the spritesheet. No rows.




	/PuppetAnimate <name> <animationName> <timeBetweenFrames> <numberOfLoops> <endFrame>/		//TODO make endframe optional		
	/PuppetAnimate Sue Dance 250 5 2/
	/PuppetAnimate Sue Laugh 100 -1 0/

Animates a puppet with an animation defined by PuppetDefineAnimation.
If <numberOfLoops> is set to -1, loops indefinitely.
If <numberOfLoops> is set to 0 or 1, only does animation once.	




	/PuppetFlip <name> <flipType>
	/PuppetFlip Sue left/

Flips the puppet.
By default puppets face right.
<flipType> options are:
	right
	left
	up









	/PuppetBoil <name> [doOffset=true] [doAnimation=true] [boilAnimationOverride=null] [timeBetweenFrames=200]/
	/PuppetBoil Aubrey/
	/PuppetBoil Aubrey false/
	/PuppetBoil Aubrey true false/
	/PuppetBoil Aubrey true false AlternativeBoilAnimation/
	/PuppetBoil Aubrey true false AlternativeBoilAnimation 500/

Animates a puppet with a boiling effect. This makes the puppet jitter.
[doOffset] jitters size and position slightly.
[doAnimation] is equal to frames 0 1 2 1 looping at 200 MS/frame. You need to prodive your own art in the spritesheet at those frames.
if [boilAnimationOverride] is set, uses that defined animation instead of frames 0 1 2 1




	/PuppetFade <fadeTimeMilliseconds> <any number of puppets>
	/PuppetFadeIn <fadeTimeMilliseconds> <any number of puppets>
	/PuppetFade 500 Sue King Toroko/
	/PuppetFadeIn 2500 Sue/

Fades puppets in or out over a set duration.






	/PuppetShow/
	/PuppetHide/
	/PuppetShow [any number of puppets]/
	/PuppetHide [any number of puppets]/
	/PuppetShow john1 john2 john3/
	/PuppetHide john1 john2 john3/

Hides or shows all puppets, or if [anyNumberOfPuppets] is added, the specifed puppets.


























































USING VARIABLES IN COMMANDS



	/$var/
	/$class.var/
	/$array/			//The entire array, separated per default by a space. Separator be changed with the /arraySep <separator>/ command.		/arraySep/(no arg = no separator)	/arraySepSpace/(space)		/arraySep _/	/arraySep ,/	/arraySep ;/	/arraySep abc/	/arraySep Hello there! Anything goes!/
	/$array.index/		//If out of bounds of array, either negative or above, it'll do nothing and the full array instead gets added with the number and dot still attached.	/$array.0/$array.1/
	/$$array/			//Random entry from array



Good usage:
Don't create a var/class/array with the same name as another var/class/array. This would make value replacement unpredictable.
Don't create a var/class/array with the same name as a vanilla dialogue command. This might break dialogue in events.
	This includes numbers, most single letters, and "action", "query".

Examples:

	/var character HatKid/move $character 10 0 0/
	/var anEntireDamnCommand move HatKid 10 0 true/$anEntireDamnCommand/

	/class someClass (character=HatKid;moveArgs=10 0 0)/move $someClass.character $someClass.moveArgs/
	/array someArray (move HatKid 10 0 0;speak HatKid \"Hello!\";jump HatKid 8)/$$someArray/






























PRECONDITIONS

Preconditions are superiour to Content Patcher's "When" field because when using the "When" field, you can't access the events through the console if the conditions aren't met.

New preconditions


	/ifChar <characterName>/
	
Check if character exists.




	/ifMod <UniqueID>/
	/ifModAny <several UniqueID>/
	/ifModAll <several UniqueID>/
	
Check if mod(s) exist.
<UniqueID> can be found in a mod's manifest.json.





	/false/
	/null/

Both make it so events can only be started through code.






























TOKENS

Tokens can be used in if statements, or anywhere else really, example:

	/if [DayOfMonth] == 24 && [Season] == spring switchEvent 123_abc/
	/var forkToGoTo EventID_someFork_[Season]/switchEvent $forkToGoTo/



Tokens get parsed when the event's fork is switched to, not when the command is called.
This means the values of tokens might be outdated by the time you get to a command that uses them.
This is rare, because most tokens such as [Season] or [DayOfMonth] do not change during an event.
Notable cases to be wary of include:
	[FreeItemSlots], [ItemCount], [Money] when a command alters the inventory, or money.
	[Hearts], [Friendship] when a command changes friendship.

To fix this you cam:
-SwitchEvent before the token.
-Use the following command:

	/parseTokens {command with (tokens) surrounded by round brackets.}/
	/parseTokens {speak HatKid \"(Money)!?? You are so rich!!!!\"}/







New tokens


	[var varname]

This is mostly redundant because you can get the value of a variable using $varName.
However this can still be used in C# code to access variables in an event.









	[Skill farming]
	[Skill mining]
	[Skill combat]
	[Skill foraging]
	[Skill fishing]
	[Skill]
	
Player's skill level.
[Skill] is all skill levels combined.

Example:

/if [Skill combat] >= 6 addAnswer \"(Combat 6) I am a competent fighter.\" 123_skillCheckSuccess/
/if [Skill combat] < 6 addAnswer \"([Skill combat]/6) I am totally a competent fighter I promise!!!!\" 123_skillCheckFail/
				










	[ItemCount <itemID>]
	[ItemCount 30]
	[ItemCount (F)30]
	
Number of items in inventory.

Example:

/speak Renata \"You have [ItemCount 66] amethysts in your inventory, and [ItemCount (BC)66] ancient tables!\"/
(BC) stands for big craftables








	[FreeItemSlots]

Number of free item slots in inventory.

	/if [FreeItemSlots] != 0 doThing/
	/if [FreeItemSlots] > 0 doThing/







	[Hearts <npc>]
	[Friendship <npc>]

Hearts (0-14) or Friendship (0 to 3500) with character.
If character does not exist, 0.

	/if [Hearts Carol] >= 10 doThing/
	/if [Friendship Carol] >= 2500 doThing/




	[Spouse]
	[Partner]
	[SpouseOrPartner]

[Spouse] = The player's spouse or roomate if he has one, else "null".
[Partner] = The player's partner if he has one, else "null".
[SpouseOrPartner] = The player's spouse or roommate or partner if he has one, else "null".

	/if [Spouse] == Morgan speak Morgan \"I love you!\"/






	[CurrentLocation]

The internal name of the current location.

	/speak Renata \"We're in the Skull Caverns! Its internal name is the [CurrentLocation]!\"/





	[Money]

The player's money.
	
	/if [Money] >= 1000 switchEvent 123_rich/







	[Print]
	[Print optional message goes here]

Debug tool that prints a message to the console to see when tokens get parsed.
Replacement is nothing.
Default message is "Print token parsed."
Fun fact: Schedules do not allow for tokens :(



















DYNAMIC DIALOGUE

[DynamicDialogue <characterName> <keyName> Optional fallback text goes here.]

This token can be used in dialogue files to select random dialogue from any number of options.
May include conditions and randomness weights.




Token format in dialogue string:

[DynamicDialogue Jas someKey Fallback text without quotes.]

Jas is the name of the dialogue file to look in. 99% of the time you want to use the name of the character speaking.
You can use this from a marriage dialogue file too to check the regular file, or any other character dialogue file.

someKey is the key to check for in the dialogue file. You can use more than 1 key by seperating keys with a / but without spaces.

Fallback is the text that is shown if there's no valid keys found.





Key format in dialogue file:

Keys can be "keyName_1" for regular entries or "keyName_-1" for fallback entries if no regular entries are found or have met conditions.

Values can be in one of 3 formats shown in the example below. Args are separated by /
Condition is a GameStateQuery. https://stardewvalleywiki.com/Modding:Game_state_queries
Weight is a float number. Default value 100. This means a value of 200 makes it 2 times as likely to be shown as others. 0.01 Makes it 10000 times as rare.
Dialogue is a normal dialogue string. This can use #$b# and #$e# or any other command as usual.

	
Token Key
	"spring_5":		"[DynamicDialogue Jas someKey/someOtherKey/yetSomeOtherKey Fallback text without quotes.]",

Entry Keys (3 formats)
	"someKey_1":	"Text option.",															//Format 1
	"someKey_2":	"Condition/Text option with conditions.",								//Format 2
	"someKey_3":	"Weight/Condition/Text option with conditions and weight.",				//Format 3
	"someKey_4":	"Weight//Text option with weight but no condition.",					//Format 3 (no condition)

	"someKey_-1":	"Fallback text option.",												//Format 1 fallback
	"someKey_-2":	"Condition/Fallback text option with conditions.",						//Format 2 fallback
	"someKey_-3":	"Weight/Condition/Fallback text option with conditions and weight.",	//Format 3 fallback
	"someKey_-4":	"Weight//Fallback text option with weight but no condition.",			//Format 3 fallback (no condition)




Fallback Priority Order. The first one found gets chosen as fallback if no keys are found. The rest are ignored.
-Text inside the token itself.			[DynamidDialogue Jas somekey This text here.]
-Keys with a _-1 _-2 _-3 suffix			"someKey_-1":	"Like so",
-A key named "fallback": "Text",		"fallback":		"Like so",







The key without a _number can be used to:
-Give a condition to all entries of that key.	(arg 1)
-Add several other keys.						(arg 2)


Giving a condition to all other numbered keys:


	"spring_1":			"[DynamicDialogue Jas busDialogue I wish the bus wasn't broken...]",
	
	"busDialogue":		"PLAYER_HAS_MAIL Current ccVault",	//This one!
	
	"busDialogue_1":	"Wow the bus is so cool!",
	"busDialogue_2":	"I love going to the desert!",
	"busDialogue_3":	"I wish the bus went to places other than the desert.",


In this case the numbered keys can only be shown when the bus is repaired, else it shows the fallback provided in the token itself.




Adding several key categories to 1 key:


	"spring_1":		"[DynamicDialogue Morgan friendship]",

	"friendship":	"/lowFriendship mediumFriendship highFriendship",	//Here!
	
	//Sub-keys are separated by spaces.
	//In this case there is no condition, but it still needs a / so that is has 2 arguments.

	"lowFriendship":		"PLAYER_HEARTS Current Morgan 0 2",
	"lowFriendship_1":		"Uhm, hi.",
	"lowFriendship_2":		"I'm Morgan. I'm a little witch girl.",
	"lowFriendship_3":		"Have you met Jas? She is very purple.",

	"mediumFriendship":		"PLAYER_HEARTS Current Morgan 3 5",
	"mediumFriendship_1":	"Hiya, mister, how are you?",
	"mediumFriendship_2":	"Are you having a nice day?",
	"mediumFriendship_3":	"Would you like to go on a magical adventure with me?",

	"highFriendship":		"PLAYER_HEARTS Current Morgan 6 14",
	"highFriendship_1":		"Wow, you are such a good friend!",
	"highFriendship_2":		"Are you having a nice day?",
	"highFriendship_3":		"Would you like to go on a magical adventure with me?",


This only works with keys from the token itself. You can not put sub-keys in "highFriendship" for example.







Make sure you order keys without missing a step.
Good:	key_1 key_2 key_3 key_4
Bad:	key_1 key_2 key_25
The code stops looking for new keys if it misses 5 steps in a row as an optimisation, instead of checking for all 1000 iterations.

Tiers of 100 exist for readability, however. Example:

	"key_1":	"Something regarding the bus",
	"key_2":	"Something regarding the bus",
	"key_3":	"Something regarding the bus",

	"key_101":	"Something regarding the train",
	"key_102":	"Something regarding the train",

	"key_901":	"Something regarding friendship",


The max number of choices per key is 1000. You're probably gonna use about 2-10.



You can test dynamicDialogue with this console command:

dd <CharacterName> key1/key2/key3/key4etc
dd Morgan friendship/train/fun
































GAMESTATEQUERRIES


New


	CHARACTER_EXISTS <characterName>

Returns true if character exists. 
Can be used to check if modded characters are in the game.















	CHARACTER_HAS_SPRITE <characterName> <spriteName>

Returns true if character's current sprite's name equals <spriteName>
<spriteName> is not case sensitive.















	IS_WEDDING_ANNIVERSARY

Returns true if today is wedding anniversary.











	SPOUSE_IS_PREGNANT

Returns true if spouse is pregnant.










	QUEST_ACTIVE <questId>

Returns true if quest is active.











	PLAYER_WEARING_HAT <id>
	PLAYER_WEARING_SHIRT <id>
	PLAYER_WEARING_PANTS <id>
	PLAYER_WEARING_BOOTS <id>
	PLAYER_WEARING_RING	<id>

Returns true if player is wearing the respective clothing piece.
IDs are unqualified.
Correct:	PLAYER_WEARING_PANTS 1000 
Wrong:		PLAYER_WEARING_PANTS (S)1000

You can use the following console command to check the IDs of the items you're wearing:	showWornItems

You can omit the argument to check if you're wearing ANY item of that type.
Example:

"PLAYER_WEARING_HAT" 

Will return true if you're wearing ANY hat.











	CHARACTER_IS_IN_LOCATION <characterName> <locations>
	CHARACTER_IS_IN_LOCATION Carol Beach Island_South Island_North Island_West Island_East

Returns true if character is in location.
Useful for appearance field from character data.
Note: This will mess up events set in temp maps, and should not be used therefor.
Find a use for it.








	IS_ODD_YEAR
	IS_EVEN_YEAR

Returns true if year is odd/even
That is 1 3 5 7 vs 2 4 6 8 etc
