Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
QTE Window


eh2lUQ7.png



Hi everyone!
This plugins aims to allow you to create QTE's on the map scene or on the battle scene.
Inately via events but using other plugins such as action sequences, as a condition to skill cast.

Version RC2:
Some code modification transparent to the user, a small bug fix. You can also now choose whether to display messages on the battle log window or not via parameters.


Features:
  • Create and display QTEs on the map scene or on the battle scene.
  • Three QTE modes: Normal (you have a time frame to complete all inputs), Free (records player input) and Rythm (the player must complete each input in it's own time frame).
  • Ocarina mode: reminiscent from Legend of Zelda Ocarina of time. Each input will make a sound, also allows the display of each input like on a music sheet. Notes are pre set to be the ocarina ones, but you can change the sounds themselves or where each icon is placed in the parameters.
  • With yanfly's core engine and battle engine core: a set of functions aimed at using QTEs as a condition for skill cast, or to match player input to a skill notetag and to cast the skill if the inputs match.
  • 6 Recognized inputs (made with keyboard and controller in mind): Up, Down, Left, Right, Ok, Cancel.

Screenshots and examples:

The examples below all use yanfly's action sequences plugin.

1 : Setting up a skill requiring a QTE as a skill cost:

Skill Notetag

<setup action>
eval: $gameMap.QTE(["normal"],300,["ok","up","down","left"],true)
if eval:$gameMap.getQTEResult() === "failure"
break action
end

</setup action>
/*
line 1: creating the QTE
line 2: get the result
line 3: if QTE failed abort action
*/

Result:
tKiFvuC.png



Rythmic QTE call and looks:

afOaXKA.png

Example: a use of a rythmic QTE to make a spell deal a critical hit if you complete it.

This example requires yanfly's damage core and critical core.

Skill notetag:
<whole action>
if (user instanceof Game_Actor)
eval: $gameMap.QTE(["rythm",2],0,[["no",Math.floor(Math.random()*50)+20],["ok",50]],true)
if ($gameMap.getQTEResult() === "success")
force critical
end
end

</whole action>
/*
line 1: if the user is an actor
line 2: create the rythmic QTE
line 3: if the QTE is a success
line 4: force a critical hit
*/


Result:

tpyc3Xt.png

Setting up a skill that will ask for player input, and then will cast the spell that matches the sequence:

Skill notetag:
<setup action>
eval: $gameMap.QTE(["free",4,"cancel"],300,[],true)
eval: $gameMap.castSkillMatch(user,target,7)
</
setup action>

My suggestion is to make a QTE casting skill that targets allies and another that targets enemies, and tell the player to use either one depending on what target type he wants.
Because if you try and target enemy n*1 in your troop with a spell that targets allies only, you'll end up healing the first party member instead.
You'll have to define the sequence to check in each spell notebox that you want to be able to cast this way.

Example:

If spark's notetag is:

<qteSeq:["ok","ok","down","down"]>
And the sequence entered in the above free mode QTE is ok ok down down, it will make the user cast spark.
Ocarina mode example:



To replicate those effects: first you have to set up an actor with the skills themselves (so in that case, create the skills, make them into a class and set an actor to that class).
In my case I created a dummy actor (n*5) that will only serve the purpose of holding the songs as skills.
Then I inside those new skills I created the notetages, for example saria's song notetag is <qteSeq:["down","right","left","down","right","left"]>.
Line by line explanation:
  • Create the QTE arguments detail:
  • Hide contents
  • Free input QTE,
  • maximum input number = 6,
  • cancel key = menu,
  • duration = 500 frames,
  • sequence doesn't matter for free mode QTEs so I set it to [],
  • visible = true,
  • x = 0,
  • y = 100,
  • opacity = 255,
  • width = 4 but this doesn't matter in the case of free input QTEs. I put it here to show that for those QTEs it will automatically set it to the number of maximum inputs.

  • Set the ocarina mode. If you want to activate the new ocarina display the call has to be $gameMap.setOcarina(true,true).
  • Create the skills possibilty window (SPW) referencing actor 5, max inputs = 6, no minimum inputs.
  • Set the SPW coordinates
  • Set the SPW width and height (set it to 500 width and 4 lines height)
  • Set how much space for the text and how much for the icons (200 for the text, 300 for the icons)
  • New script block. This is imperative or else you won't be able to get the QTE result
  • Get the skills matchs from the sequence entered (it gives their id)
  • Get the skill name from the skill match, and set it inside variable 3
  • Remove SPW
  • Display variable 3 that will contain the name of the skill that matched the player input, or nothing if there was no match.
This will play the ocarina sound as you input commands, and display the song name if you input properly.
With some additional conditionals you can make it play a failure sound (by checking if $gameMap.getSkillMatch(5) === "no match found"), or play the full song if it recognized one just like in OOT..

Ocarina display example:

CO6Zqjg.png


Song names belong to Legend of Zelda Ocarina of time. They were used only to show what the ocarina display was intended for.
Title Image Example:

<setup action>
eval: $gameMap.createSPW(user._actorId,4,1)
eval: $gameMap.setSPWSize(300,3)
eval: $gameMap.QTE(["free",4,"cancel"],300,[],true)
eval: $gameMap.removeSPW()
eval: $gameMap.trySequence(user,target,3)
</setup action>

The sequence entered in the title image is [ok up down left], fire is [ok up down] and heal is [ok up down left].
By trying the sequence the actor will cast fire (on target enemy) and then heal (on party member index = enemy index).
If I had used castSkillMatch it would have only cast Heal.
If I had used castSequencce it would have tried to cast the skills with sequences ok up down left in order.

Demo Icon Set:

4ezjq9x.jpg
Download:

Skill Possibilities Window Add on :

Terms of use: See inside the QTEWindow js file for reference. Pasted here:
// TERMS OF USE:
// Free to use both commercially and non commercially.
// For commercial games, you must provide me with a free copy of the game.
// For non commercial games, tell me about it! I'd love to see what you were able
// to do with my plugin.
// Credits required, in a visible place:
// any of Astfgl/ Pierre MATEO/ Pierre MATEO (Astfgl)
// Edits allowed, with the caveat that you must keep the edited product under the
// same license and you must clearly indicate it is an edit, and what part you
// did edit.
// You must keep this header intact.

Setup:
  • Download the Plugin file, put it inside a .js file, name it QTEWindow. If you want the addon, download the file and name it QTEAddonSPW.
  • By default this plugin uses empty spaces on the icon file for its display. I have edited the icon file and added suitable icons myself at these spaces. You can either do the same or modify the plugin parameters to look for other icon numbers. In the example screenshot you can find my modified icon file if you want to use it.
  • Setup the parameters. Everything is explained inside the plugin help file and the parameters description
Usage:
Pasted below is the plugin's help file.

* ===================================================================
* PLUGIN SETUP:
* Set the parameters before use, notably the icon indexes or the
* inputs won't show.
* If you want to use the ocarina mode, you'll have to specify
* the file names in the ocarina sounds parameter.
* If you want accurate note display you'll have to modify the note
* position array too, 36 is one full space, 18 a half space, 3 is
* just for correct spacing.
*
* ===================================================================
* SUGGESTED PLUGINS FOR BATTLE USE:
* Yanfly Core Engine, Battle Engine Core, Action sequence 1
* This is for battle use through action sequences. You can call the QTE
* using common events or another plugin providing action sequences if you want.
* I just haven't tried it. I make almost no battle modifications though
* so another plugin should work too.
*
* Look at the examples in the thread for ideas on how to use them in action
* sequences.
*
* ==================================================================
* How to call a QTE:
* $gameMap.QTE(mode,duration,sequence,visible,x*,y*,opacity*,
* width*,height*,wrongInput*,showTime*)
*
* =================
* NORMAL QTE
* mode = ["normal"]
* duration = duration wanted in frames
* sequence = sequence (see at the end of the help file how to provide sequences)
* visible = whether you want to show the qte window or not, true or false
*
* All the following parameters marked with an * are not required, but the window
* will use them instead of the plugin parameters if they are present.
* x = x position of the qte window
* y = y position of the qte window
* opacity = opacity of the back of the qte window, not the icons
* or time remaining gaug
* width = the width as in number of icons you want to show at once
* height = the height in pixels
* wrongInput = whether a wrong input will end the QTE as a failure or not,
* can be true or false
* showTime = the mode to show time, "number", "gauge", "both" or "no"
*
* ex: $gameMap.QTE(["normal"],300,["ok","up","left"],true)
*
*==================
* To set one QTE window option in particular:
*
* $gameMap.setQTEpos(x,y) = sets the x and y position of the QTE window.
* $gameMap.setQTEdim(width,height) = sets the width and height of the QTE window
* $gameMap.setQTEfail(boolean) = either true or false, whether a wrong
* Input makes the QTE stops as a failure.
* $gameMap.setQTEopacity(number) from 0 transparent to 255 opaque,
* the opacity of the QTE window, not the contents.
* $gameMap.setQTEtime(mode) sets which mode to display time, same options
* as the parameter.
* $gameMap.setQTEsound(bool) true or false, whether to play sounds or not.
* Note that this will only stop the system sounds from playing, the ocarina
* sounds will be played if applicable.
* $gameMap.setOcarina(bool,bool2) if bool = true each input will play the sound
* defined in the parameters, if bool2 = true it will switch the display mode
* of the sequence to look like a music sheet.
* ================
*
* Every QTE window option is reset at the end of each action in battle.
* On the map, the QTE window is reset each time the map is entered,
* like going in the menuand then back.
* This goes for all QTE modes.
* Reset all QTE options: $gameMap.clearQTE();
*
* ===============
* FREE QTE a QTE that registers player input
* The script call is the same as above, however the mode argument differs
* mode = ["free",maxInput,cancelButton]
* maxInput = the maximum numberof recorded keys
* cancelButton = a button to end the input.
* If you have several skills with different sequence length
* set the maxInput to the maximum sequence length. Ie fire is up up down,
* spark up up up up, set max Input to 4.
* If you want to cast spark just press up 4 times, because maxInput is reached
* the qte will end automatically. But if you want to cast Fire you'll gave to
* press up up down and then cancelButton.
* It will ignore the sequence argument, so just put [].
*
* ex: $gameMap.QTE(["free",4,"cancel"],300,[],true). This will produce a
* QTE window asking for 4 inputs, ending when running out of time or
* on the first "cancel" button press.
*================
*
* RYTHMIC QTE: ie a qte progressing by itself and you need to press each
* button in its timeframe
* The sequence is setup like this:
* [[button,duration],[button2,duration2],...,[buttonN,durationN]]
* In addition to the inputs below you can use "no", and it will wait and
* return a failure if any button is pressed during the wait.
* The mode argument is also changed mode = ["rythm",increment*]
* Increment is not mandatory, it is by how much at each frame the duration
* will diminish.
* If not set it will use 1.
* Ex: duration = 300 frame, increment 1 -> actual duration 300 frame
* duration = 300 frames, increment 5 -> actual duration 60 frames. It will make
* the qte move faster.
* Call example:
* var seq = [["ok",100],["no",50],["up",100],["down",100]]
* $gameMap.QTE(["rythm",5],300,seq,true);
*
*
* ========================================================
* How to get a QTE result: $gameMap.getQTEResult()
*
* =================
* Important:
* Please note that due to the way this works you have to use the
* getQTEResult() script call in another script event command, not in
* the same as the one where you launch the qte or it won't work.
*
* =================
* The result function has 4 possibilities:
* pending: qte not started
* start: qte currently running
* success: qte ended succesfully
* failure: qte ended in failure
*
* ex: $gameMap.getQTEResult() === "success" in a condition script will return true
* if the QTE was a success, and false for any other option.
*
* ================
* In case of a free QTE the result function will return the sequence.
* To get the skills that match the sequence entered, use the call:
* $gameMap.getSkillMatch(actorId)
* This will look through all skills of the actor, and if any of the
* sequences in their note <qteSeq:> matches that of the skill, will return
* their id.
*
* ex: $gameMap.getSkillMatch(1) will look through actor 1 skills.
*
* If you want to return the name of a skill from a match, use
* $gameMap.getSkillNameFromMatch(skillId)
*
* ex: $gameMap.getSkillNameFromMatch($getSkillMatch(1))
* That call will try to match the qte result to a skill id, and return their
* name. Assign it to a variable and you can display it.
*
* ============================================================
* DEFINING SEQUENCES:
* ============================================================
*
* Normal mode :
* Provide sequences as an array
* ["button1", button2",...,"buttonN"].
*
*
* Free mode:
* The defined sequence doesn't matter just use [].
*
*
* Rythm mode:
* Provide sequences as an array:
* [[button,duration],[button2,duration2],...[buttonN,durationN]]
* You can use "no" instead of a button if you want to make a pause
* in the QTE.
*
* ============================================================
* Use a free input QTE to cast a spell for each input:
* $gameMap.castSequence(user,target,actionAr)
* IMPORTANT This command won't work without yanfly's battle engine
* core and will crash your game if used without.
* The user and target must be the objects themselves, not the ID
* or index.
* ActionAr is the array of action to match the input in that order:
* [up,down,left,right,ok,cancel]
*
* ex: eval: $gameMap.castSequence(user,target,[30,31,32,33,34,35])
* For an input: up down left right ok
* This will make the user cast skills 30,31,32,33,34 in succession
*
* You can use v(id) inside the action array, to refer to the value
* of variable id, so you are able to modify the combos in game.
*
* ============================================================
* Use a free input QTE to cast a skill that matches its sequence.
* $gameMap.castSkillMatch(user,target,failActionId)
* This will make the user cast the matching action on target,
* if there was no match it will instead make it cast failActionId.
* If failActionId is 0, it won't do anything instead.
*
* ============================================================
* Cast both the sequence and the skill match:
* $gameMap.castSandSM(user,target,actionAr,failActionId)
* This will first go through the actions via the cast sequence
* command and then attempt to cast a match from that sequence.
* The arguments are the same as the functions described above.
*
* =============================================================
* Cast every skill match found within the sequence:
* $gameMap.trySequence(user,target,minInputs*,maxInputs*)
* Okay, this one is a bit complicated, let's take an example:
* the free QTE result is ["ok","ok","down","down"]
* Let's say min and max Inputs aren't given as instructions.
* It will cast the skills the actor know with the notetags
* <qteSeq:["ok"]> and <qteSeq:["down"]> in that order:
* ok, ok, down, down.
* Then it will move to look for matches in 2 length.
* So it will cast the spells okok, okdown and downdown
* Then do it for 3:
* okokdown, okdowndown
* Then do it for 4:
* okokdowndown
* If the actor doesn't have any skills that match those notetags
* it simply will ignore them.
* What do min Input and max Input do: they will start or end
* the process at those number.
* So if min inputs was 2 , it wouldn't have cast the skills
* that matched only 1 input. And if max Inputs was 3 it wouldn't
* have cast the final sequence of 4.
*
* =============================================================
* MAKE A RANDOM SEQUENCE
* ONLY FOR NORMAL MODE
* Use $gameMap.randomSequence(length)
* It will generate a random QTE sequence of that length, using
* all inputs available, except those you put after length
* example: $gameMap.randomSequence(5,"up") will return a 5
* input long sequence that doesn't contain the up key.
* $gameMap.randomSequence(5,"up","down") will do the same
* but without the down key too.
* example:
* $gameMap.QTE(["normal",0],500,$gameMap.randomSequence(5),true)
*
*
*
*
*
* ===========================================================
* KEY LIST
* ===========================================================
* You can find the list of keys here:
* 0: 'ok', // A
* 1: 'cancel', // B Used as cancel key in examples.
* 2: 'shift', // X Not supported
* 3: 'menu', // Y Not supported
* 4: 'pageup', // LB Not suppoted
* 5: 'pagedown', // RB Not supported
* 12: 'up', // D-pad up
* 13: 'down', // D-pad down
* 14: 'left', // D-pad left
* 15: 'right', // D-pad right
*
*/

FAQ:
  • Does this work with items?
It doesn't.
  • Is it planned to make this smartphone compatible?
I will not make this plugin compatible with touch input, or the mouse. Keyboard and controller only.
  • My input doesn't show!
That's not a question. Please be sure you have setup the plugin parameters correctly and/or the plugin file names are correct. Check the setup section.
  • Is there a way to change the note display in rythmic QTEs?
Right now there isn't. It's not very pretty but it's functional. Feel free to request customization options on that point.


Credits:
  • Astfgl66
  • Yanfly (Core engine, Battle Engine Core, Action sequences, and more)
Edit: Old forum broke the formatting, hopefully this should be much better.
 
Last edited:

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
Hi!


Just to let you know: I've made a small update. The update doesn't allow extra features, but makes several improvements to the code and fixes a small bug.


There's also new parameters so that you can toggle whether or not you want to display battle log messages for failed QTEs or free QTEs that don't match any learned skills.


Those parameters are evaled, meaning that if you put $gameSwitches.value(switchId) in there, by manipulating switch switchId you can toggle it in game.


There's no modifications to the SPW so no need to download it again.


Happy making!
 

styx92

Veteran
Veteran
Joined
Jan 7, 2016
Messages
310
Reaction score
39
First Language
German
Primarily Uses
Yeah that looks really good.


Is it possible to create a qte without a skill? Mabye at on event the player rides mabye a horse and he have to put a qte and if he fails he falls down? 


Or it only works with the ocarina system? 
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
The ocarina system is completely optionnal. You can create any type of QTE on the map as well as on the battle scene.


What you ask for can be achieved by using a normal type QTE on the map. It will look like the first example.


For example:

  • Script: 

$gameMap.QTE(["normal"],300,["ok","up","left"],true)


The player has 300 frames to enter the sequence ok up left.


You can then check the result like this:

  • Condition: Script:

$gameMap.getQTEResult() === "success"


Do  stuff on success

  • Else:

Do Stuff on failure

  • End conditionnal
 

styx92

Veteran
Veteran
Joined
Jan 7, 2016
Messages
310
Reaction score
39
First Language
German
Primarily Uses
Okay nice!


I tested it now but i get an error. I have nothing changed in the parameters. In a empty project its the same.
Still after start a new game. In my empty project is only yanfly core activ and your plugins. In my real project many more :D but the same error.

Unbenannt.PNG
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
Your plugin is incorrectly named.


The file must be named "QTEWindow" without the quotes.
 

styx92

Veteran
Veteran
Joined
Jan 7, 2016
Messages
310
Reaction score
39
First Language
German
Primarily Uses
Muhahahahaha!


Works pretty :D


i just thought something like renamed the plugin. Thanks for your support and the plugin =)
 

Psycoris

Villager
Member
Joined
Jun 4, 2014
Messages
7
Reaction score
0
First Language
English
Primarily Uses
This looks like exactly what I was looking for. I am definitely going to have to give this a try and see if it works like I am assuming it does based on the screenshot.
 

GreenBanana

Active Chain and Combo Input Skills plugin
Veteran
Joined
Mar 28, 2014
Messages
78
Reaction score
5
First Language
English
Primarily Uses
RMMV
I have encountered the following error upon starting a new game or loading a saved game with just the following plugins. This occurs in a completely new project with only the default parameters set for everything.

upload_2018-11-20_13-18-2.png
upload_2018-11-20_13-19-56.png
upload_2018-11-20_13-20-21.png

Naturally, I don't know what any of this means. I just chose this plugin because you said it could mimic the functionality of the Input Combo Skills plugin, which enables players to link several options of skills together in a row with the possibility of a finisher move if certain combinations of skills are input.

Other times, I encountered an error after a lengthy "Now Loading" screen which then failed to an error saying the game font couldn't be loaded, but I haven't been able to replicate this by will. I hope the above screenshots help.
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
Your plugins are incorrectly named.


The file must be named "QTEWindow" without the quotes.

I posted the exact same message 3 posts above in 2016. You could do 3 minutes of research, really.
 

GreenBanana

Active Chain and Combo Input Skills plugin
Veteran
Joined
Mar 28, 2014
Messages
78
Reaction score
5
First Language
English
Primarily Uses
RMMV
No other script needs a specific filename, so I reasoned you were being persnickety. Seems I was right anyway.
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
That's not true actually. Almost all plugins that use parameters need to be correctly named.
That's due to the way the plugin manager handles parameters, and is a default behaviour of the engine.
Some plugin makers have develloped another way of handling parameters. This plugin was made in 2016, I don't think this method was really common knowledge at the time. And at the very least it wasn't within my skill level.

Anyway, your first solution to errors should be to read the instructions and apply them to the letter. That's not only when using my plugins, but everyone else's too. You're bound to get errors if you interpret, because who knows if you're gonna interpret them the same way as the plugin maker ? That's exactly what happened here. And you're not the first.

Edit: and you can try it with yanfly's plugin if you want. Rename the core engine, to something other than YEP_CoreEngine, you'll see that parameters don't work at all.

Also, for something irrelevant, I don't really know what persnickety means, and a traduction doesn't bring up something useful in context.
 
Last edited:

mlogan

Global Moderators
Global Mod
Joined
Mar 18, 2012
Messages
16,742
Reaction score
9,291
First Language
English
Primarily Uses
RMMV
Scripts in Ace did not need to be so accurately named. Plugins in MV do need to be correctly named.
 

lhc1114

Warper
Member
Joined
Nov 20, 2014
Messages
4
Reaction score
1
First Language
korean
Primarily Uses
Can I display the input icons like other modes in rhythm QTE mode?
Or can I display other modes to display text like rhythm mode?
(I use a translator, sorry.)
 
Last edited:

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
You can't.
The issue here is that in rythm mode you specify a duration for each note, which correlates to the width.
Using icons for rythm mode wouldn't work because I can't stretch them or it would look terrible. Not that rythm mode looks great as is either.

You could however modify the other modes to display like rythm mode too. That would'nt be too hard, if I recall correctly. I haven't looked at this plugin in a while and it was an early work of mine.
 

Myers & Sparks

Veteran
Veteran
Joined
Jan 2, 2017
Messages
175
Reaction score
25
First Language
English
Primarily Uses
RMMV
Hey @Astfgl66

I noticed in your help file you said:

upload_2019-8-18_23-25-20.png

I understand how I would call this using common events, however could you give an example as to how to call it via action sequence?
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
There are examples in the main post.
 

Gabenslair

Villager
Member
Joined
Dec 12, 2015
Messages
27
Reaction score
3
First Language
English
Primarily Uses
N/A
Is there a way that i can imitate LISA's combo system where every single input invokes a skill alongside combo skills?
 

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
756
Reaction score
629
First Language
French
Primarily Uses
I don't know about lisa but I think the trysequence command is what you're after.
 

Gabenslair

Villager
Member
Joined
Dec 12, 2015
Messages
27
Reaction score
3
First Language
English
Primarily Uses
N/A
I don't know about lisa but I think the trysequence command is what you're after.
I would like for you to elaborate on what "try sequence" does.
Thank you for being patient.

Edit: Actually, IDK how i can implement skills. Your help file may be long, but its quite hard to follow on what your talking about.
If you could send a demo that demonstrates those said examples or a video tutorial, that will be really generous of you.
Again, thank you for your time.
 
Last edited:

Latest Threads

Latest Posts

Latest Profile Posts

Another night, another game dev stream in about 20 minutes or so.

I've been busy. Warming up so I don't forget how to draw.
Fr4yy7TaEAUB57Z
I'd make a joke about the post office, but I'm afraid you won't get it.
I've been on a really good streak lately of working on my game for at least a little bit each day. Even if I only complete one small task, it is still a much better pace than what I was maintaining previously!
I haven't worked on my game for a couple of weeks. Decided to get some things done this evening and found that my characters won't hop over to their targets to attack (Battlecore) but only when using a weapon that is a type with IDs 3 and anything above 6 in the database. Wasn't doing this before my break. Yeah, I'm done game devving. I won't allow another hobby to waste my precious time like this.

Forum statistics

Threads
129,782
Messages
1,205,074
Members
170,876
Latest member
cepatmenang22
Top