From ca700c4cfd0a99aa1c750f23a4ebf5fe99988071 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 22 Oct 2013 17:20:15 +0200 Subject: [PATCH 01/56] Creating the new branch for filters. --- manual/opencs/.gitignore | 4 ++++ manual/opencs/filters.tex | 13 +++++++++++++ manual/opencs/main.tex | 12 ++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 manual/opencs/.gitignore create mode 100644 manual/opencs/filters.tex create mode 100644 manual/opencs/main.tex diff --git a/manual/opencs/.gitignore b/manual/opencs/.gitignore new file mode 100644 index 0000000000..12930f58e4 --- /dev/null +++ b/manual/opencs/.gitignore @@ -0,0 +1,4 @@ +*.backup +*.aux +*.log +*.toc \ No newline at end of file diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex new file mode 100644 index 0000000000..5a9ca6d9ce --- /dev/null +++ b/manual/opencs/filters.tex @@ -0,0 +1,13 @@ +\section{Filters} +\subsection{Introduction} +Filters are the key element of OpenCS use cases by allowing rapid and easy access to the seeked records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ +Don't be afraid though, filters are fairly intuitive and easy to use. +\subsection{Used Terms} +\begin{description} + \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtred according to the criteria of user choice. Criteria are written down in language with simple syntax. + \item[Criteria] describes condition under with any any record is being select by the filter. + \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. Our syntax is simple and described in the {B}asics subsection. + \item[Expression] is a criteria, only written with OpenCS filter syntax. +\end{description} +\subsection{Basics} +\subsection{Advanced Usage} \ No newline at end of file diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex new file mode 100644 index 0000000000..da3457e133 --- /dev/null +++ b/manual/opencs/main.tex @@ -0,0 +1,12 @@ +\documentclass[american]{article} +\usepackage[T1]{fontenc} +\usepackage{babel} +\author{OpenMW Team} +\begin{document} + +\title{OpenCS User Manual} + +\maketitle +\tableofcontents{} +\input{filters} +\end{document} From 930aef7ae5025972f944874a06280d3af98a7bd2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 22 Oct 2013 21:25:13 +0200 Subject: [PATCH 02/56] Added *.pdf to the gitignore. --- manual/opencs/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manual/opencs/.gitignore b/manual/opencs/.gitignore index 12930f58e4..cf62bd6fc6 100644 --- a/manual/opencs/.gitignore +++ b/manual/opencs/.gitignore @@ -1,4 +1,5 @@ *.backup *.aux *.log -*.toc \ No newline at end of file +*.toc +*.pdf \ No newline at end of file From e34cbe857c7735c4a39dd3be12fd22ea94af2939 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 23 Oct 2013 12:37:28 +0200 Subject: [PATCH 03/56] Added a little more to the filters. --- manual/opencs/filters.tex | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 5a9ca6d9ce..d6ca6eb858 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -2,12 +2,41 @@ \subsection{Introduction} Filters are the key element of OpenCS use cases by allowing rapid and easy access to the seeked records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ Don't be afraid though, filters are fairly intuitive and easy to use. + \subsection{Used Terms} + \begin{description} \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtred according to the criteria of user choice. Criteria are written down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. Our syntax is simple and described in the {B}asics subsection. \item[Expression] is a criteria, only written with OpenCS filter syntax. + \item[Tokken] is any part of the expression, responsible for checking for the criteria in specified column. + \item[Node] is any part of the expression, responsible for performing logical operations on tokkens. That is: group two (or more) tokkens together in order to create a expression that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''); create any expression that will show only records that does not met criteria of specific tokken(logical ``not''). \end{description} + \subsection{Basics} -\subsection{Advanced Usage} \ No newline at end of file +To summarize and lay the very fundaments of this chapter: if you want to display filters of your choice (and you really do, because that's the use case on which opencs is designed) you have to know exactly what do you want to get in order to translate this into the tokkens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows. + +\subsection{Interface} + +\subsection{Using predefined filters} + +\subsection{Filter scopes} + +\subsubsection{Tokkens} +Each tokken is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table. +\linebreak +It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column from the value use comma. + +\paragraph{String -- string(``column'', ``value'')} +String in programmers language is often just a word for anything composed of characters. In case of OpenCS this is in fact every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string tokken.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string tokken for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified.\footnote{This is not completely valid, however at this point this approach can be useful.} +\linebreak +Since majority of the columns contain string values, string tokken is among the most often used. Examples: +\begin{itemize} + \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. + \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). +\end{itemize} +String tokken can also use regular expressions (regexps) as it's value. This will be described in the ``Advanced'' section. + +\paragraph{Value -- value(``value'', (``open'', ``close''))} +While string tokken covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight`` \ No newline at end of file From 11779c27d308063274ffd30d9ac9920878c5f5a8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 23 Oct 2013 21:34:59 +0200 Subject: [PATCH 04/56] =?UTF-8?q?Writting=20that=20manual=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manual/opencs/filters.tex | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index d6ca6eb858..be406b3c06 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -18,10 +18,38 @@ Don't be afraid though, filters are fairly intuitive and easy to use. To summarize and lay the very fundaments of this chapter: if you want to display filters of your choice (and you really do, because that's the use case on which opencs is designed) you have to know exactly what do you want to get in order to translate this into the tokkens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows. \subsection{Interface} +Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. You probabbly noticed it before. However there is alo completely new element, although using familiar table layout. Go to the application menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, description and modyfied. +\begin{description} + \item[Filter] column containing expression of the filter. + \item[Description] contains the short description of the filter function. + \item[Name] constains the name of the filter. + \item[Modyfied] just like in all other tables you have seen so far modyfied indicates if a filter was added, modyfied or removed. +\end{description} + +So let's learn how to actually use those to speed up your work. \subsection{Using predefined filters} +Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text table will magicly alters and will show only the weapons. As you could noticed project::weapons is nothing else than a name of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field. +\linebreak +To make life easier filter names follow simple convention. + +\begin{itemize} + \item Filter name filtring a specific record type contains usually the name of specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. + \item When filtering specific subgroup the name starts just like in the case of general filter. For instance project::weaponssilver will filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). + \item There are few exceptions from the above. For instance there is a project::added, project::removed, project::modyfied, project::base. You could probabbly except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. +\end{itemize} + +I strongly recommend to take a look at the filters table right now to see what you can filter with that. And try using it! It is very simple. \subsection{Filter scopes} +Back to the manual? Good. Now let's explain the cryptic project:: at the begining of every predefined filter. It is a scope. Scope determinates if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. +\begin{description} + \item[project::] scope indicates that filter is stored inside the project file. + \item[session::] scope indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Untill then it can be found inside the filters table. +\end{description} +In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed just once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you type it directly inside the filter field, starting with ``!''. +\linebreak +Still, you may wonder how you are supposed to write expressions, what and nodes tokkens are avaible, and what syntax looks like. \subsubsection{Tokkens} Each tokken is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table. From e89f1dd40a1f54a921037dc7e54970c909984b25 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 24 Oct 2013 18:33:35 +0200 Subject: [PATCH 05/56] Corrected, according to Zini. Not completly, though. --- manual/opencs/filters.tex | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index be406b3c06..d6fafc4aaf 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -1,70 +1,70 @@ \section{Filters} \subsection{Introduction} -Filters are the key element of OpenCS use cases by allowing rapid and easy access to the seeked records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ +Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ Don't be afraid though, filters are fairly intuitive and easy to use. \subsection{Used Terms} \begin{description} - \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtred according to the criteria of user choice. Criteria are written down in language with simple syntax. + \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. Our syntax is simple and described in the {B}asics subsection. \item[Expression] is a criteria, only written with OpenCS filter syntax. - \item[Tokken] is any part of the expression, responsible for checking for the criteria in specified column. - \item[Node] is any part of the expression, responsible for performing logical operations on tokkens. That is: group two (or more) tokkens together in order to create a expression that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''); create any expression that will show only records that does not met criteria of specific tokken(logical ``not''). + \item[Token] is any part of the expression, responsible for checking for the criteria in specified column. + \item[Node] is any part of the expression, responsible for performing logical operations on tokens. That is: group two (or more) tokens together in order to create a expression that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''); create any expression that will show only records that does not met criteria of specific token(logical ``not''). \end{description} \subsection{Basics} -To summarize and lay the very fundaments of this chapter: if you want to display filters of your choice (and you really do, because that's the use case on which opencs is designed) you have to know exactly what do you want to get in order to translate this into the tokkens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows. +In fact you don't need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity with OpenCS is inside basics section. \subsection{Interface} -Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. You probabbly noticed it before. However there is alo completely new element, although using familiar table layout. Go to the application menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, description and modyfied. +Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. You probably noticed it before. However there is also completely new element, although using familiar table layout. Go to the application menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, description and modified. \begin{description} + \item[ID] contains the name of the filter. + \item[Modified] just like in all other tables you have seen so far modified indicates if a filter was added, modified or removed. \item[Filter] column containing expression of the filter. \item[Description] contains the short description of the filter function. - \item[Name] constains the name of the filter. - \item[Modyfied] just like in all other tables you have seen so far modyfied indicates if a filter was added, modyfied or removed. \end{description} So let's learn how to actually use those to speed up your work. \subsection{Using predefined filters} -Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text table will magicly alters and will show only the weapons. As you could noticed project::weapons is nothing else than a name of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field. -\linebreak +Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text table will magicly alters and will show only the weapons. As you could noticed project::weapons is nothing else than a name of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field.\\ To make life easier filter names follow simple convention. \begin{itemize} - \item Filter name filtring a specific record type contains usually the name of specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. + \item Filter name filtering a specific record type contains usually the name of specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. \item When filtering specific subgroup the name starts just like in the case of general filter. For instance project::weaponssilver will filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). - \item There are few exceptions from the above. For instance there is a project::added, project::removed, project::modyfied, project::base. You could probabbly except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. + \item There are few exceptions from the above. For instance there is a project::added, project::removed, project::modyfied, project::base. You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. \end{itemize} -I strongly recommend to take a look at the filters table right now to see what you can filter with that. And try using it! It is very simple. +We strongly recommend to take a look at the filters table right now to see what you can filter with that. And try using it! It is very simple. -\subsection{Filter scopes} -Back to the manual? Good. Now let's explain the cryptic project:: at the begining of every predefined filter. It is a scope. Scope determinates if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. +\subsection{Advanced} +If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the tokens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows.\\ +Advance subsection covers everything that you need to know in order to create any filter you may want to. +\subsection{Namespaces} +It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace determinate if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. \begin{description} - \item[project::] scope indicates that filter is stored inside the project file. - \item[session::] scope indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Untill then it can be found inside the filters table. + \item[project::] namespace indicates that filter is stored inside the project file. + \item[session::] namespace indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} -In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed just once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you type it directly inside the filter field, starting with ``!''. -\linebreak -Still, you may wonder how you are supposed to write expressions, what and nodes tokkens are avaible, and what syntax looks like. +In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ +Still, you may wonder how you are supposed to write expressions, what and nodes tokens are avaible, and what syntax looks like. -\subsubsection{Tokkens} -Each tokken is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table. -\linebreak +\subsubsection{Tokens} +Each token is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table.\\ It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column from the value use comma. \paragraph{String -- string(``column'', ``value'')} -String in programmers language is often just a word for anything composed of characters. In case of OpenCS this is in fact every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string tokken.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string tokken for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified.\footnote{This is not completely valid, however at this point this approach can be useful.} +String in programmers language is often just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string token for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified.\footnote{This is not completely valid, however at this point this approach can be useful.} \linebreak -Since majority of the columns contain string values, string tokken is among the most often used. Examples: +Since majority of the columns contain string values, string token is among the most often used. Examples: \begin{itemize} \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). \end{itemize} -String tokken can also use regular expressions (regexps) as it's value. This will be described in the ``Advanced'' section. +String token can also use regular expressions (regexps) as it's value. This will be described in the ``Advanced'' section. \paragraph{Value -- value(``value'', (``open'', ``close''))} -While string tokken covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight`` \ No newline at end of file +While string token covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value token. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range. \ No newline at end of file From cef3b30b25cdb48f6004dd68e12d3b58c90999ea Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 24 Oct 2013 19:24:37 +0200 Subject: [PATCH 06/56] Added tables.tex. It is almost empty at the moment. --- manual/opencs/filters.tex | 10 +++++++--- manual/opencs/tables.tex | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 manual/opencs/tables.tex diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index d6fafc4aaf..1863987dcb 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -57,14 +57,18 @@ Each token is used in similar manner. First off: you have to write it's name (fo It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column from the value use comma. \paragraph{String -- string(``column'', ``value'')} -String in programmers language is often just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string token for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified.\footnote{This is not completely valid, however at this point this approach can be useful.} -\linebreak +String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string token for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. +\\ Since majority of the columns contain string values, string token is among the most often used. Examples: \begin{itemize} \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). \end{itemize} -String token can also use regular expressions (regexps) as it's value. This will be described in the ``Advanced'' section. +This is probably enough to create around 90\% string filters you would need. However, this token is even more powerfull -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? +\\ +Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is that mostly the mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. + +%TO-DO: write the regexps essentials. \paragraph{Value -- value(``value'', (``open'', ``close''))} While string token covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value token. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range. \ No newline at end of file diff --git a/manual/opencs/tables.tex b/manual/opencs/tables.tex new file mode 100644 index 0000000000..eab308d420 --- /dev/null +++ b/manual/opencs/tables.tex @@ -0,0 +1,10 @@ +\section{Tables} +If you launched OpenCS already and played it with for a while you surely noticed that it is a very table oriented application. Your impression is surely correct: major part of Open{CS} is built around table pattern. But this is not excel clone! Table was just the most logical way of dealing with all different record types in a general way. +\subsection{Used Terms} + +\begin{description} +\end{description} + +\subsection{Basics} + +\subsection{Advanced} From 382ca00dcb15c6b8c684732e7ec3dd1e9a473f0e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 29 Oct 2013 20:46:53 +0100 Subject: [PATCH 07/56] Still draft. I need to carefully read the text, and point out that this is all about record filters. --- manual/opencs/filters.tex | 46 +++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 1863987dcb..72b83d270f 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -9,9 +9,10 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. Our syntax is simple and described in the {B}asics subsection. - \item[Expression] is a criteria, only written with OpenCS filter syntax. - \item[Token] is any part of the expression, responsible for checking for the criteria in specified column. - \item[Node] is any part of the expression, responsible for performing logical operations on tokens. That is: group two (or more) tokens together in order to create a expression that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''); create any expression that will show only records that does not met criteria of specific token(logical ``not''). + \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record. + \item[N-ary] is any expression that is useful to group two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). + \item[unary] is any expression that expects one other expression. The example is ``not'' expression. + \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} \subsection{Basics} @@ -44,31 +45,54 @@ We strongly recommend to take a look at the filters table right now to see what If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the tokens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows.\\ Advance subsection covers everything that you need to know in order to create any filter you may want to. \subsection{Namespaces} -It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace determinate if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. +It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace of the filter determinate if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. \begin{description} \item[project::] namespace indicates that filter is stored inside the project file. \item[session::] namespace indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ -Still, you may wonder how you are supposed to write expressions, what and nodes tokens are avaible, and what syntax looks like. +Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. -\subsubsection{Tokens} -Each token is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table.\\ +\subsubsection{Nullary expressions} +Each expression is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table.\\ It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column from the value use comma. \paragraph{String -- string(``column'', ``value'')} -String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string token for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. +String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. \\ -Since majority of the columns contain string values, string token is among the most often used. Examples: +Since majority of the columns contain string values, string is among the most often used expressions. Examples: \begin{itemize} \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). \end{itemize} -This is probably enough to create around 90\% string filters you would need. However, this token is even more powerfull -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? +This is probably enough to create around 90\% string filters you would need. However, this expression is even more powerfull -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? \\ Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is that mostly the mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. %TO-DO: write the regexps essentials. +\\ +Regular expressions is not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). \paragraph{Value -- value(``value'', (``open'', ``close''))} -While string token covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value token. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range. \ No newline at end of file +While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range.\\ +As you would imagine the range can be specified as including a border value, or excluding. We are using two types of brackets for this: +\begin{itemize} + \item To include value use [] brackets. For value equal 5, expression value(something, [5, 10]) will evaluate to true. + \item To exclude value use () brackets. For value equal 5, expression value(something, (5, 10)) will evaluate to false. + \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression will evaluate to false for value equal 10. +\end{itemize} + +\subsection{Logical expressions} +This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes theme from user point of view belonging to the same group of logical expressions. + +\paragraph{not -- not expression()} +Sometimes you may be in need of reversing the output of the expression. This is where not comes in handy. Adding not before expression will revert it: if expression was returning true, it will return false; if it was returning false, it will return true. Brackets are not needed: not will revert only the first expression following it.\\ +To show this on know example, let's consider the ''string("armor type", ".* gauntlet"))`` filter. As We mentioned earlier this will return true for every gauntlet found in game. In order to show everything, but gauntlets we simply do ''not string("armor type", ".* gauntlet"))``. This is probably not the most useful filter on earth, but this is not a surprise: real value of not expression shines when combined with or, and filter. + +\paragraph{or -- or(expression1(), expression2())} +Or is a expression that will return true if one of the arguments evaluates to true. You can use two or more arguments, separated by the comma.\\ +Or expression is useful when showing two different group of records is needed. For instance the standard actor filter is using the following ''or(string(``record type'', npc), string(``record type'', creature))`` and will show both npcs and creatures. + +\paragraph{and -- and(expression1(), expression2())} +And is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by the comma.\\ +As We mentioned earlier in the ''not`` filter, combining not with and can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. \ No newline at end of file From 056833e21e50d8492589846f5f878f48779a0a15 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Oct 2013 12:57:01 +0100 Subject: [PATCH 08/56] Still filters. A little less draft-ish quality. --- manual/opencs/filters.tex | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 72b83d270f..418ead3fc5 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -8,10 +8,10 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \begin{description} \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. - \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. Our syntax is simple and described in the {B}asics subsection. - \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record. - \item[N-ary] is any expression that is useful to group two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). - \item[unary] is any expression that expects one other expression. The example is ``not'' expression. + \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. + \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record at the time. + \item[N-ary] is any expression that expects two or more expressions as arguments. It is useful for grouping two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). + \item[unary] is any expression that expects one other expression. The example is ``not'' expression. In fact ``not'' is the only useful unary expression in OpenCS record filters. \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} @@ -25,53 +25,54 @@ Above each table there is a field that is used to enter filter: either predefine \item[ID] contains the name of the filter. \item[Modified] just like in all other tables you have seen so far modified indicates if a filter was added, modified or removed. \item[Filter] column containing expression of the filter. - \item[Description] contains the short description of the filter function. + \item[Description] contains the short description of the filter function. Do not expect any surprises there. \end{description} So let's learn how to actually use those to speed up your work. \subsection{Using predefined filters} -Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text table will magicly alters and will show only the weapons. As you could noticed project::weapons is nothing else than a name of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field.\\ -To make life easier filter names follow simple convention. +Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text, table will magicly alter and will show only the weapons. As you could noticed project::weapons is nothing else than a ID of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field.\\ +To make life easier filter IDs follow simple convention. \begin{itemize} - \item Filter name filtering a specific record type contains usually the name of specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. - \item When filtering specific subgroup the name starts just like in the case of general filter. For instance project::weaponssilver will filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). - \item There are few exceptions from the above. For instance there is a project::added, project::removed, project::modyfied, project::base. You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. + \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. + \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance project::weaponssilver will filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). + \item There are few exceptions from the above rule. For instance there is a project::added, project::removed, project::modyfied, project::base. You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. \end{itemize} We strongly recommend to take a look at the filters table right now to see what you can filter with that. And try using it! It is very simple. \subsection{Advanced} -If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the tokens and nodes. Finally, you will have to write this as legal expression -- that is: using correct syntax. As a result table will show only desired rows.\\ +Back to the manual? Great.\\ +If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the expressions. Finally, you will have to write this with correct syntax. As a result table will show only desired rows.\\ Advance subsection covers everything that you need to know in order to create any filter you may want to. \subsection{Namespaces} -It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace of the filter determinate if the filter will be stored along with your project or if it will be forgotten as soon as OpenCS quits. +Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace of the filter determinate if the filter will be stored along with your project file or if it will be forgotten as soon as OpenCS quits. \begin{description} \item[project::] namespace indicates that filter is stored inside the project file. \item[session::] namespace indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ -Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. +Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. Let's start with nullary expressions that will allow you to create a basic filter. \subsubsection{Nullary expressions} -Each expression is used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: evaluated true) the record will show up in the table.\\ -It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column from the value use comma. +All nullary expressions are used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: expression will evaluate to true) the record will show up in the table.\\ +It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column argument from the value argument use comma. \paragraph{String -- string(``column'', ``value'')} -String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string token.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. +String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. \\ Since majority of the columns contain string values, string is among the most often used expressions. Examples: \begin{itemize} \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). \end{itemize} -This is probably enough to create around 90\% string filters you would need. However, this expression is even more powerfull -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? +This is probably enough to create around 90\% string filters you will eventually need. However, this expression is even more powerful -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? \\ -Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is that mostly the mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. +Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. %TO-DO: write the regexps essentials. \\ -Regular expressions is not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). +Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). \paragraph{Value -- value(``value'', (``open'', ``close''))} While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range.\\ @@ -94,5 +95,5 @@ Or is a expression that will return true if one of the arguments evaluates to tr Or expression is useful when showing two different group of records is needed. For instance the standard actor filter is using the following ''or(string(``record type'', npc), string(``record type'', creature))`` and will show both npcs and creatures. \paragraph{and -- and(expression1(), expression2())} -And is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by the comma.\\ -As We mentioned earlier in the ''not`` filter, combining not with and can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. \ No newline at end of file +And is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by a comma.\\ +As We mentioned earlier in the ''not`` filter, combining ''not`` with ''and`` can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. \ No newline at end of file From cb8d111d36866b7ff98db3d80162f62908e95d45 Mon Sep 17 00:00:00 2001 From: TomKoenderink Date: Wed, 30 Oct 2013 21:51:37 +0100 Subject: [PATCH 09/56] Started tables.tex; import library for images --- manual/opencs/img/water.png | Bin 0 -> 914 bytes manual/opencs/main.tex | 3 +- manual/opencs/tables.tex | 78 ++++++++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 manual/opencs/img/water.png diff --git a/manual/opencs/img/water.png b/manual/opencs/img/water.png new file mode 100644 index 0000000000000000000000000000000000000000..885c2d9a732fbcc138dd5b82675136753af27848 GIT binary patch literal 914 zcmeAS@N?(olHy`uVBq!ia0y~yVC)34^ElXmezgNlPf3)4h~MgeXYCYD8t3&8?SXZ`dT4V2tws5Er)=Lxf_aUO7K^kkB`rpDzX zq#&Rm)DWNu#0o+T9V`j698?$tI1gx-dwuwsF3=HMlYdBsG2xISSk$D^qk&lhXf%@x zQ^UuaDZD;{<(~^9CbKXA%@j$TbwGu&!Gi&85Q7q<&k1n`S0)Dy7bXTEn#kaw(jZ_n zU4RqFI{-8ZuI|XQoh@MAGR}z%GAn@Y`Jo7N%K=3$B}NWKC6Ku@)LfVf3MSooB=p42 z;@tGt7ehrk1UTD|E&FdCWWpl&X!FXheXC?D7i{}eo6hNa)YIvRYf~qG=QQaZ-``su zP7L|_R&AjGr<%Qj+|Ew-fAc2tFMf4ixg|+&o~MO^Ou_*z`NmR)-Ph{$fMzlSt&1~I z6f$GIA^hb*Fq@fk*3A7jFa9M=65wE%+~P3d@6}ab6J{BBGH|T$VBm0--B*~q(0Rw- z$GR&l?r=0}D87#0TYBHXvxE6Yd{ZJ&lhHn{t!_TzN{Rv&F>3@5dYr!PYi2*?R`($# zp+^jFZXG|g@m#B5hf$Rr%e8LPNoqpx=bLx`lwWVJujeEbfByb89>wcD9vm#LW_wMO z-=;jC+0xrrdidP$XiW*F#L3BT3!eX7C%~O=e)Gvavkhe&yS6EP2v5i@S|huLePYD! zg=Us~ENi$YZa7%^V(<346`z<&R+c?JV72IZ)Xcw@M^7F*=9n-0@QtRW=Zy;y{xdXO z4!JFRd2H*l6*-byEfuRY)&xs@@HuoWx$Wg;tD`r+FMn;mF4tzkuAB3Ge;hMqc&wb* t1xzxqIA%zQP_fyM?b@h2jZF!oGqTO-KPjj#h$KyF6*2UngG_9Pgno| literal 0 HcmV?d00001 diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex index da3457e133..64f9baf5c9 100644 --- a/manual/opencs/main.tex +++ b/manual/opencs/main.tex @@ -1,12 +1,13 @@ \documentclass[american]{article} \usepackage[T1]{fontenc} \usepackage{babel} +\usepackage{graphicx} \author{OpenMW Team} \begin{document} \title{OpenCS User Manual} - \maketitle \tableofcontents{} +\input{tables} \input{filters} \end{document} diff --git a/manual/opencs/tables.tex b/manual/opencs/tables.tex index eab308d420..1a9b362d1b 100644 --- a/manual/opencs/tables.tex +++ b/manual/opencs/tables.tex @@ -1,10 +1,82 @@ \section{Tables} -If you launched OpenCS already and played it with for a while you surely noticed that it is a very table oriented application. Your impression is surely correct: major part of Open{CS} is built around table pattern. But this is not excel clone! Table was just the most logical way of dealing with all different record types in a general way. + +\subsection{Introduction} +If you have launched OpenCS already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. You'd be spot on: OpenCS is built around using tables. This doesn't mean it works just like Excel or Calc, though. Due to the vast amounts of information involved with Morrowind, tables just made the most sense. You have to be able to spot information quickly and be able to change them on the fly. Let's browse through the various screens and see what all these tables show. + + + \subsection{Used Terms} +\subsubsection{Glossary} + \begin{description} + \item[Record:] An entry in OpenCS representing an item, location, sound, NPC or anything else. + + \item[Reference, Referenceable:] When an item is placed in the world, it doesn't create a new record each time. For example, the game world might contain a lot of exquisite belts on different NPCs and in many crates, but they all refer to one specific record: the Exquisite Belt record. In this case, all those belts in crates and on NPCs are references. The central Exquisite Belt record is called a referenceable. This allows modders to make changes to all items of the same type. For example, if you want all exquisite belts to have 4000 enchantment points rather than 400, you will only need to change the referenceable Exquisite Belt rather than all exquisite belts references individually. \end{description} -\subsection{Basics} +\subsubsection{Recurring Terms} -\subsection{Advanced} +Some columns are recurring throughout OpenCS. They show up in (nearly) every table in OpenCS. + +\begin{description} + \item[ID]: Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. For example, the ID for the (unique) black pants of Caius Cosades is "Caius_pants". This allows you to manipulate the game in many ways. For example, you could add these pants to your inventory by simply opening the console and write: player->addItem Caius_pants. Either way, in both Morrowind and OpenCS, the ID is the primary way to identify all these different parts of the game. + + \item[Modified]: This column shows what has happened (if something has happened) to this record. There are four possible states in which it can exist. + \begin{description} + \item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with optionally the Bloodmoon and Tribunal expansions. + \item[Added] means that this record was not in the base game and has been added by a modder. + \item[Modified] means that the record is part of the base game, but has been changed in some way. + \item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences in the game itself have been removed! For example, if you remove the CharGen_Bed entry from morrowind.esm, it doesn't mean the bedroll in the basement of the Census and Excise Office in Seyda Neen is gone. You're going to have to delete that reference yourself or make sure that that object is replaced by something that still exists otherwise you'll get crashes in the worst case scenario. + \end{description} +\end{description} + + + +\subsection{World Screens} + +The contents of the game world can be changed by choosing one of the options in the appropriate menu at the top of the screen. + +\subsubsection{Regions} + +This describes the general areas of Vvardenfell. Each of these areas has different rules about things such as encounters and weather. + +\begin{description} + \item[Name:] This is how the game will show your location in-game. + \item[Map Colour:] This is a six-digit hexidecimal representation of the colour used to identify the region on the map available in World > Region Map. If you don't have an application with a colour picker, you can use your favourite search engine to find a colour picker online. + \item[Sleep Encounter:] These are the rules for what kind of enemies you might encounter when you sleep outside in the wild. +\end{description} + +\subsubsection{Cells} + +Expansive worlds such as Vvardenfell, with all its items, NPCs, etc. have a lot going on simultaneously. But if you are in Balmora, why would the computer need to keep track the exact locations of NPCs walking through the corridors in a Vivec canton? All that work would be quite useless and bring your system to its knees! So the world has been divided up into squares we call "cells". Once your character enters a cell, the game will load everything that is going on in that cell so you can interact with it. + +In the original Morrowind this could be seen when you were travelling and you would see a small loading bar at the bottom of the screen; you had just entered a new cell and the game would have to load all the items and NPCs. The Cells screen in OpenCS provides you with a list of cells in the game, both the interior cells (houses, dungeons, mines, etc.) and the exterior cells (the outside world). + +\begin{description} + \item[Sleep Forbidden:] Can the player sleep on the floor? In most cities it is forbidden to sleep outside. Sleeping in the wild carries its own risks of attack, though, and this entry lets you decide if a player should be allowed to sleep on the floor in this cell or not. + + \item[Interior Water:] Should water be rendered in this interior cell? The game world consists of an endless ocean at height 0. Then the landscape is added. If part of the landscape goes below height 0, the player will see water. (See illustration.) + + Setting the cell's Interior Water to true tells the game that this cell is both an interior cell (inside a building, for example, rather than in the open air) but that there still needs to be water at height 0. This is useful for dungeons or mines that have water in them. + + Setting the cell's Interior Water to false tells the game that the water at height 0 should not be used. Remember that cells that are in the outside world are exterior cells and should thus \textit{always} be set to false! + + \item[Interior Sky:] Should this interior cell have a sky? This is a rather unique case. The \textit{Tribunal} expansion took place in a city on the mainland. Normally this would require the city to be composed of exterior cells so it has a sky, weather and the like. But if the player is in an exterior cell and looks at his in-game map, he sees Vvardenfell with an overview of all exterior cells. The player would have to see the city's very own map, as if he was walking around in an interior cell. + + So the developers decided to create a workaround and take a bit of both: The whole city would technically work exactly like an interior cell, but it would need a sky as if it was an exterior cell. That's what this is. This is why the vast majority of the cells you will find in this screen will have this option set to false: It's only meant for these "fake exteriors". + + \item[Region:] To which Region does this cell belong? This has an impact on the way the game handles weather and encounters in this area. It is also possible for a cell not to belong to any region. + +\end{description} + +\subsubsection{Referenceables} + +This is a library of all the items, triggers, containers, NPCs, etc. in the game. There are several kinds of Record Types. Depending on which type a record is, it will need specific information to function. For example, an NPC needs a value attached to its aggression level. A chest, of course, does not. All Record Types contain at least a model. How else would the player see them? Usually they also have a Name, which is what you see when you hover your reticle over the object. + +Let's go through all Record Types and discuss what you can tell OpenCS about them. + +\begin{description} + \item[Activator:] This is an item that, when activated, starts a script or even just shows a tooltip. + \end{description} +\end{description} \ No newline at end of file From 0141526c557981e013816d982823bdae51bb9bc5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 31 Oct 2013 10:21:10 +0100 Subject: [PATCH 10/56] Corrected tables.tex so it will compile. --- manual/opencs/filters.tex | 3 +-- manual/opencs/tables.tex | 20 ++++++-------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 418ead3fc5..14181f68c8 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -68,10 +68,9 @@ Since majority of the columns contain string values, string is among the most of \end{itemize} This is probably enough to create around 90\% string filters you will eventually need. However, this expression is even more powerful -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? \\ -Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. +Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers.\\ %TO-DO: write the regexps essentials. -\\ Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). \paragraph{Value -- value(``value'', (``open'', ``close''))} diff --git a/manual/opencs/tables.tex b/manual/opencs/tables.tex index 1a9b362d1b..fb6d41ba8d 100644 --- a/manual/opencs/tables.tex +++ b/manual/opencs/tables.tex @@ -3,8 +3,6 @@ \subsection{Introduction} If you have launched OpenCS already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. You'd be spot on: OpenCS is built around using tables. This doesn't mean it works just like Excel or Calc, though. Due to the vast amounts of information involved with Morrowind, tables just made the most sense. You have to be able to spot information quickly and be able to change them on the fly. Let's browse through the various screens and see what all these tables show. - - \subsection{Used Terms} \subsubsection{Glossary} @@ -20,18 +18,13 @@ If you have launched OpenCS already and played around with it for a bit, you hav Some columns are recurring throughout OpenCS. They show up in (nearly) every table in OpenCS. \begin{description} - \item[ID]: Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. For example, the ID for the (unique) black pants of Caius Cosades is "Caius_pants". This allows you to manipulate the game in many ways. For example, you could add these pants to your inventory by simply opening the console and write: player->addItem Caius_pants. Either way, in both Morrowind and OpenCS, the ID is the primary way to identify all these different parts of the game. - - \item[Modified]: This column shows what has happened (if something has happened) to this record. There are four possible states in which it can exist. - \begin{description} - \item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with optionally the Bloodmoon and Tribunal expansions. - \item[Added] means that this record was not in the base game and has been added by a modder. - \item[Modified] means that the record is part of the base game, but has been changed in some way. - \item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences in the game itself have been removed! For example, if you remove the CharGen_Bed entry from morrowind.esm, it doesn't mean the bedroll in the basement of the Census and Excise Office in Seyda Neen is gone. You're going to have to delete that reference yourself or make sure that that object is replaced by something that still exists otherwise you'll get crashes in the worst case scenario. +\item[ID] Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. For example, the ID for the (unique) black pants of Caius Cosades is ``Caius\_pants''. This allows you to manipulate the game in many ways. For example, you could add these pants to your inventory by simply opening the console and write: ``player->addItem Caius\_pants''. Either way, in both Morrowind and OpenCS, the ID is the primary way to identify all these different parts of the game. %Wrong! Cells do not have ID, only name. +\item[Modified] This column shows what has happened (if something has happened) to this record. There are four possible states in which it can exist. +\item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with optionally the Bloodmoon and Tribunal expansions. +\item[Added] means that this record was not in the base game and has been added by a modder. +\item[Modified] means that the record is part of the base game, but has been changed in some way. +\item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences in the game itself have been removed! For example, if you remove the CharGen\_Bed entry from morrowind.esm, it doesn't mean the bedroll in the basement of the Census and Excise Office in Seyda Neen is gone. You're going to have to delete that reference yourself or make sure that that object is replaced by something that still exists otherwise you'll get crashes in the worst case scenario. \end{description} -\end{description} - - \subsection{World Screens} @@ -78,5 +71,4 @@ Let's go through all Record Types and discuss what you can tell OpenCS about the \begin{description} \item[Activator:] This is an item that, when activated, starts a script or even just shows a tooltip. - \end{description} \end{description} \ No newline at end of file From 8ae38eaa1f03699b50c65548e318ac474f064cf9 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 1 Nov 2013 13:52:24 +0100 Subject: [PATCH 11/56] Corrected few things and added short description for creating and saving filter, as well as replacing the default filters set. --- manual/opencs/filters.tex | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 14181f68c8..8f4469fc79 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -45,7 +45,7 @@ We strongly recommend to take a look at the filters table right now to see what Back to the manual? Great.\\ If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the expressions. Finally, you will have to write this with correct syntax. As a result table will show only desired rows.\\ Advance subsection covers everything that you need to know in order to create any filter you may want to. -\subsection{Namespaces} +\subsubsection{Namespaces} Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace of the filter determinate if the filter will be stored along with your project file or if it will be forgotten as soon as OpenCS quits. \begin{description} \item[project::] namespace indicates that filter is stored inside the project file. @@ -82,7 +82,7 @@ As you would imagine the range can be specified as including a border value, or \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression will evaluate to false for value equal 10. \end{itemize} -\subsection{Logical expressions} +\susubbsection{Logical expressions} This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes theme from user point of view belonging to the same group of logical expressions. \paragraph{not -- not expression()} @@ -95,4 +95,12 @@ Or expression is useful when showing two different group of records is needed. F \paragraph{and -- and(expression1(), expression2())} And is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by a comma.\\ -As We mentioned earlier in the ''not`` filter, combining ''not`` with ''and`` can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. \ No newline at end of file +As We mentioned earlier in the ''not`` filter, combining ''not`` with ''and`` can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. + +\subsubsection{Creating and saving filter} +In order to create and save new filter, you should go to the filters table, right click and select option ``add record'' from the context menu. A horizontal widget group at the bottom of the table should show up. From there you should select a namespace responsible for scope of the filter (described earlier) and desired ID of the filter. After pressing ok button new entry will show up in the filters table. This filter does nothing at the moment, since it still lacks expressions. In order to add your formula simply double click the filter cell of the new entry and write it down there.\\ +Done! You are free to use your filter. + +\subsubsection{Replacing the default filters set} +{OpenCS} allows you to substitute default filters set provided by us, with your own filters. In order to do so you should create a new project, add desired filters, remove undesired and save. Rename the file to the ``defaultfilters'' (don't forget to remove .omwaddon.project extension) and place it inside your configuration directory.\\ +The file acts as template for all new project files from now. If you wish to go back to the old default set, simply rename or remove the custom file. \ No newline at end of file From 83029244642b109d1b66fcaa481a51cfb63b7fb3 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 1 Nov 2013 13:54:34 +0100 Subject: [PATCH 12/56] corrected typo --- manual/opencs/filters.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 8f4469fc79..f69f6d7f1b 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -82,7 +82,7 @@ As you would imagine the range can be specified as including a border value, or \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression will evaluate to false for value equal 10. \end{itemize} -\susubbsection{Logical expressions} +\subsubsection{Logical expressions} This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes theme from user point of view belonging to the same group of logical expressions. \paragraph{not -- not expression()} From 2f5ad4c16f0752bab3af669535953a1cdbd90da2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 6 Nov 2013 21:10:00 +0100 Subject: [PATCH 13/56] Small changes. --- manual/opencs/filters.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index f69f6d7f1b..2c5e0939e8 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -3,7 +3,7 @@ Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ Don't be afraid though, filters are fairly intuitive and easy to use. -\subsection{Used Terms} +\subsubsection{Used Terms} \begin{description} \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. @@ -15,10 +15,10 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} -\subsection{Basics} +\subsubsection{Basics} In fact you don't need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity with OpenCS is inside basics section. -\subsection{Interface} +\subsubsection{Interface} Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. You probably noticed it before. However there is also completely new element, although using familiar table layout. Go to the application menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, description and modified. \begin{description} @@ -29,7 +29,7 @@ Above each table there is a field that is used to enter filter: either predefine \end{description} So let's learn how to actually use those to speed up your work. -\subsection{Using predefined filters} +\subsubsection{Using predefined filters} Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text, table will magicly alter and will show only the weapons. As you could noticed project::weapons is nothing else than a ID of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field.\\ To make life easier filter IDs follow simple convention. @@ -83,7 +83,7 @@ As you would imagine the range can be specified as including a border value, or \end{itemize} \subsubsection{Logical expressions} -This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes theme from user point of view belonging to the same group of logical expressions. +This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes them (from the user point of view) belonging to the same group of logical expressions. \paragraph{not -- not expression()} Sometimes you may be in need of reversing the output of the expression. This is where not comes in handy. Adding not before expression will revert it: if expression was returning true, it will return false; if it was returning false, it will return true. Brackets are not needed: not will revert only the first expression following it.\\ From 470616ce9274031bfbb26fec5e06482e030403b9 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 6 Nov 2013 22:01:37 +0100 Subject: [PATCH 14/56] Added windows.tex. Does not contain a lot at this point. --- manual/opencs/main.tex | 1 + manual/opencs/windows.tex | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 manual/opencs/windows.tex diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex index 64f9baf5c9..603e2d9ba3 100644 --- a/manual/opencs/main.tex +++ b/manual/opencs/main.tex @@ -8,6 +8,7 @@ \title{OpenCS User Manual} \maketitle \tableofcontents{} +\input{windows} \input{tables} \input{filters} \end{document} diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex new file mode 100644 index 0000000000..ad1d2f951c --- /dev/null +++ b/manual/opencs/windows.tex @@ -0,0 +1,12 @@ +\section{Windows} +\subsection{Introduction} +This section describes the multiple windows interface of the OpenCS editor. This design principle was chosen in order to extend the flexibility of the editor, especially on the multiple screens setups and on environments providing advanced windows management features, like; for instance; multiple desktops found commonly on many open source desktop environments. However, it is enough to have a single large screen to see the advantages of this concept.\\ +OpenCS windows interface is easy to describe and understand. In fact We decided to minimize use of many windows concepts applied commonly in various applications. For instance dialog windows are really hard to find in the OpenCS. You are free to try, though.\\ +Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly focused on practical ways of organizing work with the OpenCS. + +\subsection{Basics} +After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some window widgets. You are free to do so, just try to explore the menubar. \\ +You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's just focus on the windows itself. + +\paragraph{Creating new windows} +is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} widgets. \ No newline at end of file From 1eaca1e26b4933ebb8ad3a29d69879059a8a6f7f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 13 Nov 2013 21:01:48 +0100 Subject: [PATCH 15/56] Added regular expressions tutorial. Because serpentine failed me :( --- manual/opencs/filters.tex | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 2c5e0939e8..2a3d1a4800 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -70,8 +70,15 @@ This is probably enough to create around 90\% string filters you will eventually \\ Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers.\\ -%TO-DO: write the regexps essentials. -Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). +Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined latters -- that is: latters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what latters you want to match (word is composed by latters).\\ + +Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``^'' anchor and ``\$''. Putting ``^`` will tell to Open{CS} to look on the beginning of string, while ''\$`` is used to mark the end of it. For instance, pattern ''^Pink.* elephant.\$`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It doe not matter what is in between because ''.*`` is used.\\ + +You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) latters? Well, this is when ``[|]'' comes in handy. If you write something like: ``^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ + +And What if you want to match more than just one latter, just use ``(|)`` it is pretty similar to the above, but it is used to fit more than just one character. For instance: ''^(Pink|Green).* (elephant|crocodile).\$`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ + +Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure. \paragraph{Value -- value(``value'', (``open'', ``close''))} While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range.\\ From 078745c5d3a8f445127ec3dbc50020c3598251b0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 13 Nov 2013 21:28:09 +0100 Subject: [PATCH 16/56] Added some shiny PR to the windows, honestly. It is just at the begining of the manual, so maybe it will raise morale of the user ;-) --- manual/opencs/filters.tex | 6 +++--- manual/opencs/windows.tex | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 2a3d1a4800..93c29c439a 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -70,15 +70,15 @@ This is probably enough to create around 90\% string filters you will eventually \\ Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers.\\ -Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined latters -- that is: latters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what latters you want to match (word is composed by latters).\\ +Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what letters you want to match (word is composed by letters).\\ Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``^'' anchor and ``\$''. Putting ``^`` will tell to Open{CS} to look on the beginning of string, while ''\$`` is used to mark the end of it. For instance, pattern ''^Pink.* elephant.\$`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It doe not matter what is in between because ''.*`` is used.\\ -You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) latters? Well, this is when ``[|]'' comes in handy. If you write something like: ``^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ +You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when ``[|]'' comes in handy. If you write something like: ``^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ And What if you want to match more than just one latter, just use ``(|)`` it is pretty similar to the above, but it is used to fit more than just one character. For instance: ''^(Pink|Green).* (elephant|crocodile).\$`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ -Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure. +Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure.\\ \paragraph{Value -- value(``value'', (``open'', ``close''))} While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range.\\ diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index ad1d2f951c..3efe77f494 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -9,4 +9,19 @@ After starting Open{CS} and choosing content files to use a editor window should You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's just focus on the windows itself. \paragraph{Creating new windows} -is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} widgets. \ No newline at end of file +is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} widgets. + +\paragraph{Closing opened window} +is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. Closing last Open{CS} window will also terminate application session. + +\paragraph{Multi-everything} +is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any widgets you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing widget of the same type, well most likely you are able to do so.\\ + +The principle behind this design decision is easy to see for Bethesda made editor, but maybe not so clear for users who are just about to begin their wonderful journey of modding.\\ + +\subsection{Advanced} +So why? Why this is created in such manner. The answer is frankly simple: because it is effective. When creating a mod, you often have to work only with just one table. For instance you are just balancing weapons damage and other statistics. It makes sense to have all the space for just that one table. More often, you are required to work with two and switch them from time to time. All major graphical environments commonly present in operating systems comes with switcher feature, that is a key shortcut to change active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work with two at the time, and with one from time to time. Here, you can have one window holding two table widgets, and second holding just one.\\ + +Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one flexible approach in all cases.\\ + +There is no point in digging deeper in the windows of Open{CS}. Let's explore widgets, starting with tables. \ No newline at end of file From 6197ebd35f8e46fb51b7a699216bdb45e90f9852 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 13 Nov 2013 21:37:27 +0100 Subject: [PATCH 17/56] Actually builds now. --- manual/opencs/filters.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 93c29c439a..f13f51c8a1 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -72,11 +72,11 @@ Creating regexps can be a difficult and annoying -- especially when you need com Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what letters you want to match (word is composed by letters).\\ -Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``^'' anchor and ``\$''. Putting ``^`` will tell to Open{CS} to look on the beginning of string, while ''\$`` is used to mark the end of it. For instance, pattern ''^Pink.* elephant.\$`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It doe not matter what is in between because ''.*`` is used.\\ +Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It doe not matter what is in between because ''.*`` is used.\\ -You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when ``[|]'' comes in handy. If you write something like: ``^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ +You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when ``[|]'' comes in handy. If you write something like: ``\^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``\^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ -And What if you want to match more than just one latter, just use ``(|)`` it is pretty similar to the above, but it is used to fit more than just one character. For instance: ''^(Pink|Green).* (elephant|crocodile).\$`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ +And What if you want to match more than just one latter, just use ``(|)`` it is pretty similar to the above, but it is used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure.\\ From 28a98df3aa2390fedcb1d9a6027a9c6b7ec49942 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 13 Nov 2013 21:49:29 +0100 Subject: [PATCH 18/56] Some corrections. --- manual/opencs/filters.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index f13f51c8a1..0499fb7f92 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -1,4 +1,4 @@ -\section{Filters} +\section{Record filters} \subsection{Introduction} Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ Don't be afraid though, filters are fairly intuitive and easy to use. @@ -10,7 +10,7 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \item[Criteria] describes condition under with any any record is being select by the filter. \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record at the time. - \item[N-ary] is any expression that expects two or more expressions as arguments. It is useful for grouping two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). + \item[N-ary] is any expression that expects one or more expressions as arguments. It is useful for grouping two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). \item[unary] is any expression that expects one other expression. The example is ``not'' expression. In fact ``not'' is the only useful unary expression in OpenCS record filters. \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} From 17d41ff032d1f3a70048cead94ef3a3a7699211c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 14 Nov 2013 08:22:52 +0100 Subject: [PATCH 19/56] Corrected according to the zini suggestions. --- manual/opencs/filters.tex | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 0499fb7f92..82834e02cb 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -44,14 +44,14 @@ We strongly recommend to take a look at the filters table right now to see what \subsection{Advanced} Back to the manual? Great.\\ If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the expressions. Finally, you will have to write this with correct syntax. As a result table will show only desired rows.\\ -Advance subsection covers everything that you need to know in order to create any filter you may want to. +Advance subsection covers everything that you need to know in order to create any filter you may want to %TODO the filter part is actually wrong \subsubsection{Namespaces} -Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace of the filter determinate if the filter will be stored along with your project file or if it will be forgotten as soon as OpenCS quits. +Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace always means scope of the said object\footnote{You are not supposed to understand this at the moment.}. But what does it mean in case of filters? Well, short explanation is actually simple. \begin{description} - \item[project::] namespace indicates that filter is stored inside the project file. - \item[session::] namespace indicates that filter is not stored inside the project file, and once you will quit OpenCS (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. + \item[project::] namespace indicates that filter is used with the project, in multiple sessions. You can restart Open{CS} and filter is still there. + \item[session::] namespace indicates that filter is not stored trough multiple sessions and once you will quit Open{CS} (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} -In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ +In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored (even during single session) anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. Let's start with nullary expressions that will allow you to create a basic filter. \subsubsection{Nullary expressions} @@ -89,6 +89,9 @@ As you would imagine the range can be specified as including a border value, or \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression will evaluate to false for value equal 10. \end{itemize} +\paragraph{''true`` and ''false``} +Nullary ''true`` and ''false`` do not accept any arguments, and always evaluates to true (in case of ''true``) and false (in case of ''false``) no matter what. The main usage of this expressions is the give users ability to quickly disable some part of the filter that makes heavy use of the logical expressions. + \subsubsection{Logical expressions} This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes them (from the user point of view) belonging to the same group of logical expressions. From 99f72d4b612e40d5eea539b1fc3a8c94ec5cfd3d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 14 Nov 2013 08:35:03 +0100 Subject: [PATCH 20/56] =?UTF-8?q?Filters:=20typos.=20Windows:=20widgets?= =?UTF-8?q?=E2=86=92name=20panels.=20I=20have=20no=20idea=20why=20we=20are?= =?UTF-8?q?=20inventin=20our=20own=20terms=20here.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manual/opencs/filters.tex | 4 ++-- manual/opencs/windows.tex | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 82834e02cb..cf0fc72026 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -72,11 +72,11 @@ Creating regexps can be a difficult and annoying -- especially when you need com Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what letters you want to match (word is composed by letters).\\ -Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It doe not matter what is in between because ''.*`` is used.\\ +Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It does not matter what is in between, because ''.*`` is used.\\ You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when ``[|]'' comes in handy. If you write something like: ``\^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``\^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ -And What if you want to match more than just one latter, just use ``(|)`` it is pretty similar to the above, but it is used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ +And What if you want to match more than just one latter? Just use ``(|)``. it is pretty similar to the above one letter as you see, but it is used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure.\\ diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index 3efe77f494..b5b34e7881 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -5,23 +5,25 @@ OpenCS windows interface is easy to describe and understand. In fact We decided Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly focused on practical ways of organizing work with the OpenCS. \subsection{Basics} -After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some window widgets. You are free to do so, just try to explore the menubar. \\ +After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some name panels\footnote{Also known as widgets.}. You are free to do so, just try to explore the menubar. \\ You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's just focus on the windows itself. \paragraph{Creating new windows} -is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} widgets. +is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} name panels. \paragraph{Closing opened window} is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. Closing last Open{CS} window will also terminate application session. \paragraph{Multi-everything} -is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any widgets you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing widget of the same type, well most likely you are able to do so.\\ +is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any name panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing name panels of the same type, well most likely you are able to do so.\\ The principle behind this design decision is easy to see for Bethesda made editor, but maybe not so clear for users who are just about to begin their wonderful journey of modding.\\ \subsection{Advanced} -So why? Why this is created in such manner. The answer is frankly simple: because it is effective. When creating a mod, you often have to work only with just one table. For instance you are just balancing weapons damage and other statistics. It makes sense to have all the space for just that one table. More often, you are required to work with two and switch them from time to time. All major graphical environments commonly present in operating systems comes with switcher feature, that is a key shortcut to change active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work with two at the time, and with one from time to time. Here, you can have one window holding two table widgets, and second holding just one.\\ +So why? Why this is created in such manner. The answer is frankly simple: because it is effective. When creating a mod, you often have to work only with just one table. For instance you are just balancing weapons damage and other statistics. It makes sense to have all the space for just that one table. More often, you are required to work with two and switch them from time to time. All major graphical environments commonly present in operating systems comes with switcher feature, that is a key shortcut to change active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work with two at the time, and with one from time to time. Here, you can have one window holding two tables, and second holding just one.\\ Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one flexible approach in all cases.\\ -There is no point in digging deeper in the windows of Open{CS}. Let's explore widgets, starting with tables. \ No newline at end of file +There is no point in digging deeper in the windows of Open{CS}. Let's explore name panels, starting with tables. + +%We should write some tips and tricks here. \ No newline at end of file From dcfff7d457d913b4f694d983e06e0ee7be6a1907 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 14 Nov 2013 12:32:58 +0100 Subject: [PATCH 21/56] Correcting some epic fail. --- manual/opencs/windows.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index b5b34e7881..3bdfa63626 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -5,17 +5,17 @@ OpenCS windows interface is easy to describe and understand. In fact We decided Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly focused on practical ways of organizing work with the OpenCS. \subsection{Basics} -After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some name panels\footnote{Also known as widgets.}. You are free to do so, just try to explore the menubar. \\ +After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some panels\footnote{Also known as widgets.}. You are free to do so, just try to explore the menubar. \\ You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's just focus on the windows itself. \paragraph{Creating new windows} -is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} name panels. +is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} panels. \paragraph{Closing opened window} is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. Closing last Open{CS} window will also terminate application session. \paragraph{Multi-everything} -is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any name panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing name panels of the same type, well most likely you are able to do so.\\ +is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing panels of the same type, well most likely you are able to do so.\\ The principle behind this design decision is easy to see for Bethesda made editor, but maybe not so clear for users who are just about to begin their wonderful journey of modding.\\ @@ -24,6 +24,6 @@ So why? Why this is created in such manner. The answer is frankly simple: becaus Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one flexible approach in all cases.\\ -There is no point in digging deeper in the windows of Open{CS}. Let's explore name panels, starting with tables. +There is no point in digging deeper in the windows of Open{CS}. Let's explore panels, starting with tables. %We should write some tips and tricks here. \ No newline at end of file From 9b34e4a523a0251631a4e55b94b2e0ffe8085439 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 19 Nov 2013 20:35:57 +0100 Subject: [PATCH 22/56] Creating new files. --- manual/opencs/creating_file.tex | 0 manual/opencs/files_and_directories.tex | 24 ++++++++++++++++++++++++ manual/opencs/main.tex | 2 ++ 3 files changed, 26 insertions(+) create mode 100644 manual/opencs/creating_file.tex create mode 100644 manual/opencs/files_and_directories.tex diff --git a/manual/opencs/creating_file.tex b/manual/opencs/creating_file.tex new file mode 100644 index 0000000000..e69de29bb2 diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex new file mode 100644 index 0000000000..4938ff0a9a --- /dev/null +++ b/manual/opencs/files_and_directories.tex @@ -0,0 +1,24 @@ +\section{Files and Directories} +\subsection{Introduction} +As you imagine, there is no other way to store and distribute computer data without files. You surely know that each file in your file system is identified by the unique path. This is basic knowledge, and applies to both Open{MW} and Open{CS} alike.\\ + +Needless to say, this chapter describes paths and files that are used/created/edited with OpenCS editor.\\ + +\subsection{Used terms} %TODO + +\subsection{Basics} + +\paragraph{Directories} +Open{CS} user should consider two directory paths in his system. So called ``User Configuration Path'' and ``Data Path''. ``User Configuration Path'' stores basically all Open{MW} specific files that are supposed to be touched by the user, while ``Data Path''%This is wrong, pay no mind to it. + +\paragraph{Files} +Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files.\\ + +Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. Finally, We can describe the difference between those two file types use case with pure statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that. + +%TODO describe some characteristics, like file extensions. What about project files? + +The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. + +\paragraph{Dependencies} +Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. \ No newline at end of file diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex index 603e2d9ba3..577b7078b3 100644 --- a/manual/opencs/main.tex +++ b/manual/opencs/main.tex @@ -8,6 +8,8 @@ \title{OpenCS User Manual} \maketitle \tableofcontents{} +\input{files_and_directories} +\input{creating_file} \input{windows} \input{tables} \input{filters} From 9bf38372180032739fbd9ffb370276e1ac9aa2e5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 19 Nov 2013 20:38:22 +0100 Subject: [PATCH 23/56] minor edit --- manual/opencs/files_and_directories.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 4938ff0a9a..530d7a76a3 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -11,7 +11,7 @@ Needless to say, this chapter describes paths and files that are used/created/ed \paragraph{Directories} Open{CS} user should consider two directory paths in his system. So called ``User Configuration Path'' and ``Data Path''. ``User Configuration Path'' stores basically all Open{MW} specific files that are supposed to be touched by the user, while ``Data Path''%This is wrong, pay no mind to it. -\paragraph{Files} +\paragraph{Content files} Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files.\\ Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. Finally, We can describe the difference between those two file types use case with pure statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that. @@ -21,4 +21,6 @@ Game and Addon files are concept descended from old esm/esp system, but much mor The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. \paragraph{Dependencies} -Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. \ No newline at end of file +Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. + +\paragraph{Resources files} From 240a44f932292db6a5afcab9d12c47c2eeb3eff6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 19 Nov 2013 20:43:29 +0100 Subject: [PATCH 24/56] Files chapter will actually require resarch to be done :/ --- manual/opencs/files_and_directories.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 530d7a76a3..e88018af2f 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -21,6 +21,11 @@ Game and Addon files are concept descended from old esm/esp system, but much mor The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. \paragraph{Dependencies} -Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. +Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do.\\ + +Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can't depend on addon files. + +\paragraph{Loading order} \paragraph{Resources files} +%textures, sounds, whatever \ No newline at end of file From 000606efc02c28cc8bad6636af407aa34a6b5095 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 20 Nov 2013 20:05:22 +0100 Subject: [PATCH 25/56] =?UTF-8?q?working,=20working=E2=80=A6=20it=20takes?= =?UTF-8?q?=20ages.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manual/opencs/files_and_directories.tex | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index e88018af2f..307a5565f8 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -12,14 +12,20 @@ Needless to say, this chapter describes paths and files that are used/created/ed Open{CS} user should consider two directory paths in his system. So called ``User Configuration Path'' and ``Data Path''. ``User Configuration Path'' stores basically all Open{MW} specific files that are supposed to be touched by the user, while ``Data Path''%This is wrong, pay no mind to it. \paragraph{Content files} -Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files.\\ +Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ -Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. Finally, We can describe the difference between those two file types use case with pure statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that. +Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. Finally, We can describe the difference between those two file types use case with pure statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ %TODO describe some characteristics, like file extensions. What about project files? The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. +\paragraph{Project files} +Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need or want to distribute project files among players, but for sure you will want to aid all your colleagues working together with you on, well project. As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found it will be created.\\ +Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file. + +%TODO where are they stored. + \paragraph{Dependencies} Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do.\\ From 3f1eb42d9128bbbd2f5ca62b20e2de1d120e63a4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 20 Nov 2013 20:54:35 +0100 Subject: [PATCH 26/56] I hate this chapter. --- manual/opencs/files_and_directories.tex | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 307a5565f8..9ffa138289 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -9,22 +9,27 @@ Needless to say, this chapter describes paths and files that are used/created/ed \subsection{Basics} \paragraph{Directories} -Open{CS} user should consider two directory paths in his system. So called ``User Configuration Path'' and ``Data Path''. ``User Configuration Path'' stores basically all Open{MW} specific files that are supposed to be touched by the user, while ``Data Path''%This is wrong, pay no mind to it. +Open{MW} and Open{CS} uses multiple directories on file systems, however from end user perspective only two matters. That's it: user path and game path.\\ + +User path is the per user path that holds both configuration files and the content/project files (described later). Game path on the other hand, is the location of your game (most likely Morrowind\texttrademark). + +%TODO give correct path \paragraph{Content files} Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ -Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. Finally, We can describe the difference between those two file types use case with pure statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ +Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. We can describe the difference between those two file types use case with clean statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ %TODO describe some characteristics, like file extensions. What about project files? -The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. +The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder. Open{CS} scans for content files not only data subfolder but also the game path, most likely directory where you installed or unpacked Morrowind\texttrademark. However it is probably better to not pollute game path, and use only data path for Open{MW} content files, both when creating and only playing with others content files.\\ \paragraph{Project files} Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need or want to distribute project files among players, but for sure you will want to aid all your colleagues working together with you on, well project. As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found it will be created.\\ -Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file. +Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file.\\ %TODO where are they stored. +Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and the place where Open{CS} look for already existing files. \paragraph{Dependencies} Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do.\\ From 1875dea243b5fbc5bc365cec9c31f4e2f6cbc0cb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 21 Nov 2013 13:47:01 +0100 Subject: [PATCH 27/56] Making progress on corrections. --- manual/opencs/files_and_directories.tex | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 9ffa138289..0fd5932d50 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -1,35 +1,39 @@ \section{Files and Directories} \subsection{Introduction} -As you imagine, there is no other way to store and distribute computer data without files. You surely know that each file in your file system is identified by the unique path. This is basic knowledge, and applies to both Open{MW} and Open{CS} alike.\\ - -Needless to say, this chapter describes paths and files that are used/created/edited with OpenCS editor.\\ +This section of the manual covers usage of files and directories by the OpenCS. Files and directories are file system concepts, and you are probably already familiar with it. We won't try to explain this concepts, we will just focus on Open{CS}. \subsection{Used terms} %TODO \subsection{Basics} \paragraph{Directories} -Open{MW} and Open{CS} uses multiple directories on file systems, however from end user perspective only two matters. That's it: user path and game path.\\ +Open{MW} and Open{CS} uses multiple directories on file systems. First of, there is a \textbf{user directory} that holds configuration files and few different folders. The location of the user directory is hard coded for each supported operating system.\\ -User path is the per user path that holds both configuration files and the content/project files (described later). Game path on the other hand, is the location of your game (most likely Morrowind\texttrademark). +%TODO list paths. -%TODO give correct path +In addition to this single hard coded directory, both Open{MW} and Open{CS} need a place to seek for actual data files of the game: textures, models, sounds and files that store records of objects in game; dialogues and so one -- so called content files. We support multiple such paths (We call it \textbf{data paths}) as specified in the configuration. Usually one data path points to the directory where original Morrowind\texttrademark is either installed or unpacked. You are free to specify as many data paths as you would like, however, there is one special data path that, as described later, is used to store newly created content files. \paragraph{Content files} -Bethesda Morrowind engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing, mostly because large esp files could hurt stability. Open{MW} supports both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ +Bethesda Morrowind\texttrademark engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing. You would expect the esm (master) file is used to specify one master, that is modified by the esps plugins, and indeed: this is the basic idea. However, original expansions also were made as esm files, even though they essentially could be described as a really large plugins, and therefore rather use esp files. There were technical reasons behind this decision -- somewhat valid in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. Open{MW} achieves this with our own content file types.\\ +We support both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ -Game and Addon files are concept descended from old esm/esp system, but much more flexible and cleaner. We can describe the difference between those two file types use case with clean statements. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. The addon size is not a factor here. The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ +The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data path mentioned earlier).\\ +\subparagraph{Open{MW} content files} +Game and Addon files are concept somewhat similar to the old esm/esp, only in the way it should be from the very beginning. Nothing easier to describe. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. Nothing else matters: The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ -%TODO describe some characteristics, like file extensions. What about project files? +Other simple thing about content files are extensions. We are using .omwaddon for addon files and .omwgame for game files.\\ -The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder. Open{CS} scans for content files not only data subfolder but also the game path, most likely directory where you installed or unpacked Morrowind\texttrademark. However it is probably better to not pollute game path, and use only data path for Open{MW} content files, both when creating and only playing with others content files.\\ +%TODO describe what content files contains. and what not. + +\subparagraph{Morrowind content files} +Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, more than ten years \paragraph{Project files} -Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need or want to distribute project files among players, but for sure you will want to aid all your colleagues working together with you on, well project. As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found it will be created.\\ +Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files among players, but for sure you will want to aid all your colleagues working together with you on, well project. As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found, it will be created.\\ Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file.\\ %TODO where are they stored. -Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and the place where Open{CS} look for already existing files. +Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and the place where Open{CS} look for already existing files.\\ \paragraph{Dependencies} Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do.\\ From b52b6a8e7e426304f01812bff4d3d08fbaaaf704 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 21 Nov 2013 13:50:23 +0100 Subject: [PATCH 28/56] Small correction, added tiny comment. --- manual/opencs/files_and_directories.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 0fd5932d50..85d6ccec9b 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -26,10 +26,11 @@ Other simple thing about content files are extensions. We are using .omwaddon fo %TODO describe what content files contains. and what not. \subparagraph{Morrowind content files} -Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, more than ten years +Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, more than ten years %not finished \paragraph{Project files} -Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files among players, but for sure you will want to aid all your colleagues working together with you on, well project. As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found, it will be created.\\ +Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files at all, they are meant to be used only by you.\\ +As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found, it will be created.\\ Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file.\\ %TODO where are they stored. From 45203c160fa42b75d70c39802c1c27bd310ec142 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 21 Nov 2013 20:07:37 +0100 Subject: [PATCH 29/56] rearranging, correcting, small changes -- nothing interesting. --- manual/opencs/files_and_directories.tex | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 85d6ccec9b..3d418d5977 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -17,7 +17,6 @@ In addition to this single hard coded directory, both Open{MW} and Open{CS} need Bethesda Morrowind\texttrademark engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing. You would expect the esm (master) file is used to specify one master, that is modified by the esps plugins, and indeed: this is the basic idea. However, original expansions also were made as esm files, even though they essentially could be described as a really large plugins, and therefore rather use esp files. There were technical reasons behind this decision -- somewhat valid in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. Open{MW} achieves this with our own content file types.\\ We support both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ -The actual creating of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data path mentioned earlier).\\ \subparagraph{Open{MW} content files} Game and Addon files are concept somewhat similar to the old esm/esp, only in the way it should be from the very beginning. Nothing easier to describe. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. Nothing else matters: The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ @@ -26,7 +25,16 @@ Other simple thing about content files are extensions. We are using .omwaddon fo %TODO describe what content files contains. and what not. \subparagraph{Morrowind content files} -Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, more than ten years %not finished +Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, since 2002 thousands of esp/ems files were created, some with really outstanding content. Because of this Open{CS} simply has no other choice but support esp/esm files. However, if you decided to choose esp/esm file instead using our own content file types you are most likely aim at the original engine compatibility. This subject is covered in the very last section of this manual.\\ %not finished TODO add the said section. Most likely when more features are present. + +The actual creation of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data directory mentioned earlier).\\ + +\subparagraph{Dependencies} +Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. Again, please remember that this section of the manual does not cover creating the content files -- it is only theoretical introduction to the subject. For now just keep in mind that dependencies exist, and is up to you what to decide if your content file should depend on other content file.\\ + +Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file (excluding original and dirty esp/esm system) at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can't depend on addon files.\\ + +\subparagraph{Loading order} \paragraph{Project files} Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files at all, they are meant to be used only by you.\\ @@ -36,12 +44,5 @@ Project files extension is, to not surprise ``.project''. The whole name of the %TODO where are they stored. Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and the place where Open{CS} look for already existing files.\\ -\paragraph{Dependencies} -Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do.\\ - -Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can't depend on addon files. - -\paragraph{Loading order} - \paragraph{Resources files} %textures, sounds, whatever \ No newline at end of file From 05245c15af9e660cea93a2a02eaad9be89c420ff Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 22 Nov 2013 09:44:32 +0100 Subject: [PATCH 30/56] Nothing interesting. Just keeping sync. --- manual/opencs/files_and_directories.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 3d418d5977..1ef53b137c 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -42,7 +42,7 @@ As you would imagine, project file makes sense only in combination with actual c Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file.\\ %TODO where are they stored. -Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and the place where Open{CS} look for already existing files.\\ +Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and a place where Open{CS} looks for already existing files.\\ \paragraph{Resources files} %textures, sounds, whatever \ No newline at end of file From c5acfbf1337cf753c5be5d32877238d6ab67a7bd Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 22 Nov 2013 14:44:39 +0100 Subject: [PATCH 31/56] Started introduction to the resources files. --- manual/opencs/files_and_directories.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 1ef53b137c..032a7cdce4 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -45,4 +45,5 @@ Project files extension is, to not surprise ``.project''. The whole name of the Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and a place where Open{CS} looks for already existing files.\\ \paragraph{Resources files} -%textures, sounds, whatever \ No newline at end of file +%textures, sounds, whatever +Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is esp, esm or new Open{MW} file type do not contain any of those, it's clear that they have to be deliver with a different file. It is also clear that this, let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. Therefore this section must cover ways to add resources files to your content file, and point out what is supported. We are going to do just that. Later, you will learn how to make use of those files in your content. \ No newline at end of file From 400831faf82bd31a4ba123df89899eef65ac66ad Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 26 Nov 2013 15:51:59 +0100 Subject: [PATCH 32/56] Added short overiview of resources avaible. Thanks for assistance and insight on this, serpentine, lgro and scrawl. --- manual/opencs/files_and_directories.tex | 29 +++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index 032a7cdce4..b4af951b39 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -35,15 +35,40 @@ Since addon is supposed to change the game it is logical that it also depends on Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file (excluding original and dirty esp/esm system) at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can't depend on addon files.\\ \subparagraph{Loading order} +%TODO \paragraph{Project files} Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files at all, they are meant to be used only by you.\\ As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found, it will be created.\\ -Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance awesomeswords.omwaddon file is associated with awesomeswords.omwaddon.project file.\\ +Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance swords.omwaddon file is associated with swords.omwaddon.project file.\\ %TODO where are they stored. Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and a place where Open{CS} looks for already existing files.\\ \paragraph{Resources files} %textures, sounds, whatever -Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is esp, esm or new Open{MW} file type do not contain any of those, it's clear that they have to be deliver with a different file. It is also clear that this, let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. Therefore this section must cover ways to add resources files to your content file, and point out what is supported. We are going to do just that. Later, you will learn how to make use of those files in your content. \ No newline at end of file +Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is esp, esm or new Open{MW} file type do not contain any of those, it's clear that they have to be deliver with a different file. It is also clear that this, let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. Therefore this section must cover ways to add resources files to your content file, and point out what is supported. We are going to do just that. Later, you will learn how to make use of those files in your content. + +\subparagraph{Audio} +Open{MW} is using {FF}mpeg for audio playback, and so we support every audio type that is supported by this library. This makes a huge list. Below is only small portion of supported file types. + +\begin{description} + \item mp3 popular format and \textit{de facto} standard for storing audio. Used by the Morrowind game. + \item mp4 format with a better compression rate than mp3, but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. + \item ogg open source, audio container file using high quality vorbis codec. Recommended. +\end{description} + + +\subparagraph{Video} +As in the case of audio files, we are using {FFmepg} to decode video files. The list of supported files is long, we will cover only the most significant. + +\begin{description} + \item bik videos used by original Morrowind game. + \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, but since game logic is not running during cut scenes we can recommended it for use with Open{MW}. + \item ogv alternative, open source container using theora codec for video and vorbis for audio. +\end{description} + +\subparagraph{Textures and images} +Original Morrowind game uses dds and tga file for all kind of two dimensional images and textures alike. In addition, engine supported bmp files for some reason (bmp is a terrible format for a video game). We also support extended set of image files -- including jpeg and png. Jpeg and png files can be useful in some cases, for instance jpeg file is a valid option for skybox texture and png can useful for masks. However please, keep in mind that jpeg can grow into large sizes quickly and are not the best option with directx rendering backend. + +\subparagraph{Meshes} %TODO once we will support something more than just nifs \ No newline at end of file From e03b8ac39313217d4f36e1f8807a3f0ab8a01563 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 1 Dec 2013 01:06:03 +0100 Subject: [PATCH 33/56] Added *.out files to gitignore. Signed-off-by: Lukasz Gromanowski --- manual/opencs/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manual/opencs/.gitignore b/manual/opencs/.gitignore index cf62bd6fc6..ce5852a376 100644 --- a/manual/opencs/.gitignore +++ b/manual/opencs/.gitignore @@ -2,4 +2,5 @@ *.aux *.log *.toc -*.pdf \ No newline at end of file +*.pdf +*.out From 7c2afc43f4cac1c55f149e37a33a68edae16e937 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 1 Dec 2013 01:07:08 +0100 Subject: [PATCH 34/56] Small reformatting. Broked long lines, removed unneeded hard line breaks, added defs for common words. Signed-off-by: Lukasz Gromanowski --- manual/opencs/files_and_directories.tex | 107 ++++++++++---- manual/opencs/filters.tex | 179 ++++++++++++++++++------ manual/opencs/main.tex | 18 ++- manual/opencs/tables.tex | 73 +++++++--- manual/opencs/windows.tex | 47 +++++-- 5 files changed, 313 insertions(+), 111 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index b4af951b39..ce686d56cb 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -1,74 +1,119 @@ \section{Files and Directories} \subsection{Introduction} -This section of the manual covers usage of files and directories by the OpenCS. Files and directories are file system concepts, and you are probably already familiar with it. We won't try to explain this concepts, we will just focus on Open{CS}. +This section of the manual covers usage of files and directories by the OpenCS. Files and directories are file system concepts, +and you are probably already familiar with it. We won't try to explain this concepts, we will just focus on Open{CS}. \subsection{Used terms} %TODO \subsection{Basics} \paragraph{Directories} -Open{MW} and Open{CS} uses multiple directories on file systems. First of, there is a \textbf{user directory} that holds configuration files and few different folders. The location of the user directory is hard coded for each supported operating system.\\ +Open{MW} and Open{CS} uses multiple directories on file systems. First of, there is a \textbf{user directory} that holds configuration +files and few different folders. The location of the user directory is hard coded for each supported operating system. %TODO list paths. - -In addition to this single hard coded directory, both Open{MW} and Open{CS} need a place to seek for actual data files of the game: textures, models, sounds and files that store records of objects in game; dialogues and so one -- so called content files. We support multiple such paths (We call it \textbf{data paths}) as specified in the configuration. Usually one data path points to the directory where original Morrowind\texttrademark is either installed or unpacked. You are free to specify as many data paths as you would like, however, there is one special data path that, as described later, is used to store newly created content files. +In addition to this single hard coded directory, both Open{MW} and Open{CS} need a place to seek for actual data files of the game: +textures, models, sounds and files that store records of objects in game; dialogues and so one -- so called content files. We support +multiple such paths (We call it \textbf{data paths}) as specified in the configuration. Usually one data path points to the directory +where original Morrowind\texttrademark is either installed or unpacked. You are free to specify as many data paths as you would like, +however, there is one special data path that, as described later, is used to store newly created content files. \paragraph{Content files} -Bethesda Morrowind\texttrademark engine is using two types of files: esm (master) and esp (plugin). The distinction between those is not clear, and often confusing. You would expect the esm (master) file is used to specify one master, that is modified by the esps plugins, and indeed: this is the basic idea. However, original expansions also were made as esm files, even though they essentially could be described as a really large plugins, and therefore rather use esp files. There were technical reasons behind this decision -- somewhat valid in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. Open{MW} achieves this with our own content file types.\\ -We support both esm and esp files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``.\\ +\BS \MW engine is using two types of files: ESM (master) and ESP (plugin). The distinction between those +is not clear, and often confusing. You would expect the ESM (master) file is used to specify one master, that is modified by the ESPs plugins, +and indeed: this is the basic idea. However, original expansions also were made as ESM files, even though they essentially could be +described as a really large plugins, and therefore rather use ESP files. There were technical reasons behind this decision -- somewhat valid +in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. Open{MW} achieves +his with our own content file types. + +We support both ESM and ESP files, but in order to make use of new features of OpenMW one should consider using new file types designed +with our engine in mind: game files and addon files together called ``content files``. \subparagraph{Open{MW} content files} -Game and Addon files are concept somewhat similar to the old esm/esp, only in the way it should be from the very beginning. Nothing easier to describe. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. Nothing else matters: The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that.\\ +Game and Addon files are concept somewhat similar to the old ESM/ESP, only in the way it should be from the very beginning. Nothing easier +to describe. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. +If you want to create a addon for existing game file -- simply create addon file. Nothing else matters: The only distinction you should +consider is if your project is about changing other game, or creating a new one. Simple as that. -Other simple thing about content files are extensions. We are using .omwaddon for addon files and .omwgame for game files.\\ +Other simple thing about content files are extensions. We are using .omwaddon for addon files and .omwgame for game files. %TODO describe what content files contains. and what not. +\subparagraph{\MW content files} +Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players +wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very +successful project. Yay!}. Also, since 2002 thousands of ESP/ESM files were created, some with really outstanding content. +Because of this Open{CS} simply has no other choice but support ESP/ESM files. However, if you decided to choose ESP/ESM file instead +using our own content file types you are most likely aim at the original engine compatibility. This subject is covered in the very +last section of this manual. %not finished TODO add the said section. Most likely when more features are present. -\subparagraph{Morrowind content files} -Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very successful project. Yay!}. Also, since 2002 thousands of esp/ems files were created, some with really outstanding content. Because of this Open{CS} simply has no other choice but support esp/esm files. However, if you decided to choose esp/esm file instead using our own content file types you are most likely aim at the original engine compatibility. This subject is covered in the very last section of this manual.\\ %not finished TODO add the said section. Most likely when more features are present. - -The actual creation of new files is described in the next chapter. Here We are gonna focus only on details that you need to know in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data directory mentioned earlier).\\ +The actual creation of new files is described in the next chapter. Here we are gonna focus only on details that you need to know +in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files +are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data directory mentioned earlier). \subparagraph{Dependencies} -Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can't work otherwise. Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That's right: we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island for a game) or other addon files (house on the said island). It is a a good idea to be dependent only on files that are really changed in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. Again, please remember that this section of the manual does not cover creating the content files -- it is only theoretical introduction to the subject. For now just keep in mind that dependencies exist, and is up to you what to decide if your content file should depend on other content file.\\ +Since addon is supposed to change the game it is logical that it also depends on the said game. It simply can not work otherwise. +Just think about it: your modification is changing prize of the iron sword. But what if there is no iron sword in game? That is right: +we get nonsense. What you want to do is to tie your addon to the files you are changing. Those can be either game files (expansion island +for a game) or other addon files (house on the said island). It is a good idea to be dependent only on files that are really changed +in your addon obviously, but sadly there is no other way to achieve this than knowing what you want to do. Again, please remember that +this section of the manual does not cover creating the content files -- it is only theoretical introduction to the subject. For now just +keep in mind that dependencies exist, and is up to you what to decide if your content file should depend on other content file. -Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file (excluding original and dirty esp/esm system) at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can't depend on addon files.\\ - -\subparagraph{Loading order} -%TODO +Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file (excluding original +and dirty ESP/ESM system) at the time and therefore no game file can depend on other game file, and since game file makes the base +for addon files -- it can not depend on addon files. +%\subparagraph{Loading order} %TODO \paragraph{Project files} -Project files act as containers for data not used by the Openm{MW} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably don't need and/or want to distribute project files at all, they are meant to be used only by you.\\ -As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work on new content file and project file was not found, it will be created.\\ -Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file with appended extensions. For instance swords.omwaddon file is associated with swords.omwaddon.project file.\\ +Project files act as containers for data not used by the Open{MW} game engine itself, but still useful for OpenCS. The shining example +of this data category are without doubt record filters (described in the later section of the manual you are reading currently). +As a mod author you probably do not need and/or want to distribute project files at all, they are meant to be used only by you. + +As you would imagine, project file makes sense only in combination with actual content files. In fact, each time you start to work +on new content file and project file was not found, it will be created. +Project files extension is, to not surprise ``.project''. The whole name of the project file is the whole name of the content file +with appended extensions. For instance swords.omwaddon file is associated with swords.omwaddon.project file. %TODO where are they stored. -Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly created project files, and a place where Open{CS} looks for already existing files.\\ +Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly +created project files, and a place where Open{CS} looks for already existing files. \paragraph{Resources files} %textures, sounds, whatever -Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is esp, esm or new Open{MW} file type do not contain any of those, it's clear that they have to be deliver with a different file. It is also clear that this, let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. Therefore this section must cover ways to add resources files to your content file, and point out what is supported. We are going to do just that. Later, you will learn how to make use of those files in your content. +Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: +models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is ESP, ESM or new Open{MW} +file type do not contain any of those, it is clear that they have to be deliver with a different file. It is also clear that this, +let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than +a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. +Therefore this section must cover ways to add resources files to your content file, and point out what is supported. We are going +to do just that. Later, you will learn how to make use of those files in your content. \subparagraph{Audio} -Open{MW} is using {FF}mpeg for audio playback, and so we support every audio type that is supported by this library. This makes a huge list. Below is only small portion of supported file types. +Open{MW} is using {FF}mpeg for audio playback, and so we support every audio type that is supported by this library. This makes a huge list. +Below is only small portion of supported file types. \begin{description} - \item mp3 popular format and \textit{de facto} standard for storing audio. Used by the Morrowind game. - \item mp4 format with a better compression rate than mp3, but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. - \item ogg open source, audio container file using high quality vorbis codec. Recommended. + \item mp3 (MPEG-1 Part 3 Layer 3) popular audio file format and \textit{de facto} standard for storing audio. Used by the Morrowind game. + \item ogg open source, multimedia container file using high quality vorbis audio codec. Recommended. \end{description} - \subparagraph{Video} -As in the case of audio files, we are using {FFmepg} to decode video files. The list of supported files is long, we will cover only the most significant. +As in the case of audio files, we are using {FFmepg} to decode video files. The list of supported files is long, we will cover +only the most significant. \begin{description} \item bik videos used by original Morrowind game. - \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, but since game logic is not running during cut scenes we can recommended it for use with Open{MW}. + \item mp4 multimedia container which use more advanced codecs (MPEG-4 Parts 2,3,10) with a better audio and video compression rate, + but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. + \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, + but since game logic is not running during cut scenes we can recommended it for use with Open{MW}. \item ogv alternative, open source container using theora codec for video and vorbis for audio. \end{description} \subparagraph{Textures and images} -Original Morrowind game uses dds and tga file for all kind of two dimensional images and textures alike. In addition, engine supported bmp files for some reason (bmp is a terrible format for a video game). We also support extended set of image files -- including jpeg and png. Jpeg and png files can be useful in some cases, for instance jpeg file is a valid option for skybox texture and png can useful for masks. However please, keep in mind that jpeg can grow into large sizes quickly and are not the best option with directx rendering backend. +Original \MW game uses DDS and TGA files for all kind of two dimensional images and textures alike. In addition, engine supported BMP +files for some reason (BMP is a terrible format for a video game). We also support extended set of image files -- including JPEG and PNG. +JPEG and PNG files can be useful in some cases, for instance JPEG file is a valid option for skybox texture and PNG can useful for masks. +However please, keep in mind that JPEG can grow into large sizes quickly and are not the best option with DirectX rendering backend. -\subparagraph{Meshes} %TODO once we will support something more than just nifs \ No newline at end of file +%\subparagraph{Meshes} %TODO once we will support something more than just nifs \ No newline at end of file diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index cf0fc72026..e3781619c9 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -1,25 +1,38 @@ \section{Record filters} \subsection{Introduction} -Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you.\\ +Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. +Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in +the this section of the manual are perfectly clear to you. + Don't be afraid though, filters are fairly intuitive and easy to use. \subsubsection{Used Terms} \begin{description} - \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. + \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according + to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written + down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. - \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: written with correct syntax. - \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record at the time. - \item[N-ary] is any expression that expects one or more expressions as arguments. It is useful for grouping two (or more) other expressions together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). - \item[unary] is any expression that expects one other expression. The example is ``not'' expression. In fact ``not'' is the only useful unary expression in OpenCS record filters. + \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: + written with correct syntax. + \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates + either to the true or false for every column record at the time. + \item[N-ary] is any expression that expects one or more expressions as arguments. It is useful for grouping two (or more) other expressions + together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). + \item[unary] is any expression that expects one other expression. The example is ``not'' expression. In fact ``not'' is the only useful + unary expression in OpenCS record filters. \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} \subsubsection{Basics} -In fact you don't need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity with OpenCS is inside basics section. +In fact you don't need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity +with OpenCS is inside basics section. \subsubsection{Interface} -Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. You probably noticed it before. However there is also completely new element, although using familiar table layout. Go to the application menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, description and modified. +Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. +You probably noticed it before. However there is also completely new element, although using familiar table layout. Go to the application +menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, +description and modified. \begin{description} \item[ID] contains the name of the filter. @@ -30,87 +43,161 @@ Above each table there is a field that is used to enter filter: either predefine So let's learn how to actually use those to speed up your work. \subsubsection{Using predefined filters} -Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables table and type in the filters field the following: ``project::weapons''. As soon as you complete the text, table will magicly alter and will show only the weapons. As you could noticed project::weapons is nothing else than a ID of one of the predefined filters. That's it: in order to use the filter inside the table you simply type it's name inside the filter field.\\ +Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables +table and type in the filters field the following: ``project::weapons''. As soon as you complete the text, table will magicly alter +and will show only the weapons. As you could noticed project::weapons is nothing else than a ID of one of the predefined filters. That is it: +in order to use the filter inside the table you simply type it is name inside the filter field. + To make life easier filter IDs follow simple convention. \begin{itemize} - \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance project::weapons filter contains the word weapons (did you noticed?). Plural form is always used. - \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance project::weaponssilver will filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). - \item There are few exceptions from the above rule. For instance there is a project::added, project::removed, project::modyfied, project::base. You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only help to break your keyboard faster. + \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance project::weapons filter + contains the word weapons (did you noticed?). Plural form is always used. + \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance project::weaponssilver will + filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and + project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). + \item There are few exceptions from the above rule. For instance there is a project::added, project::removed, project::modyfied, project::base. + You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only + help to break your keyboard faster. \end{itemize} We strongly recommend to take a look at the filters table right now to see what you can filter with that. And try using it! It is very simple. \subsection{Advanced} -Back to the manual? Great.\\ -If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the expressions. Finally, you will have to write this with correct syntax. As a result table will show only desired rows.\\ +Back to the manual? Great. + +If you want to create your own filter you have to know exactly what do you want to get in order to translate this into the expressions. +Finally, you will have to write this with correct syntax. As a result table will show only desired rows. + Advance subsection covers everything that you need to know in order to create any filter you may want to %TODO the filter part is actually wrong \subsubsection{Namespaces} -Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the C++ language. In case of OpenCS namespace always means scope of the said object\footnote{You are not supposed to understand this at the moment.}. But what does it mean in case of filters? Well, short explanation is actually simple. +Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the \CPP{} language. +In case of OpenCS namespace always means scope of the said object\footnote{You are not supposed to understand this at the moment.}. +But what does it mean in case of filters? Well, short explanation is actually simple. \begin{description} - \item[project::] namespace indicates that filter is used with the project, in multiple sessions. You can restart Open{CS} and filter is still there. - \item[session::] namespace indicates that filter is not stored trough multiple sessions and once you will quit Open{CS} (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. + \item[project::] namespace indicates that filter is used with the project, in multiple sessions. You can restart Open{CS} and filter + is still there. + \item[session::] namespace indicates that filter is not stored trough multiple sessions and once you will quit Open{CS} (close session) + the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} -In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored (even during single session) anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that you don't need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with ``!''.\\ -Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. Let's start with nullary expressions that will allow you to create a basic filter. +In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored (even during single session) +anywhere and as the name implies they are supposed to be created when needed only once. Good thing about the one-shot filters is that +you do not need to open filters table in order to create it. Instead you just type it directly inside the filter field, starting with +exclamation mark: ``!''. + +Still, you may wonder how you are supposed to write expressions, what expressions you should use, and what syntax looks like. Let's start +with nullary expressions that will allow you to create a basic filter. \subsubsection{Nullary expressions} -All nullary expressions are used in similar manner. First off: you have to write it's name (for instance: ``string'') and secondly: condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet by a record (technical speaking: expression will evaluate to true) the record will show up in the table.\\ -It is clear that you need to know what are you checking, that's is: what column of the table contains information that you are interested in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column you want to see, while the second one sets desired value inside of the cell. To separate column argument from the value argument use comma. +All nullary expressions are used in similar manner. First off: you have to write it is name (for instance: ``string'') and secondly: +condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet +by a record (technical speaking: expression will evaluate to true) the record will show up in the table. + +It is clear that you need to know what are you checking, that is: what column of the table contains information that you are interested +in and what should be inside specific cell inside this column to meet your requirements. In most cases first word inside brackets sets column +you want to see, while the second one sets desired value inside of the cell. To separate column argument from the value argument use comma. \paragraph{String -- string(``column'', ``value'')} -String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression.\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, when record contains in the specified column exactly the same value as specified. -\\ +String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} +just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed +of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression. +\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, +when record contains in the specified column exactly the same value as specified. + Since majority of the columns contain string values, string is among the most often used expressions. Examples: \begin{itemize} - \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. This group contains every weapon (including arrows and bolts) found in the game. - \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. This group contains every portable light sources (lanterns, torches etc.). + \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. + This group contains every weapon (including arrows and bolts) found in the game. + \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. + This group contains every portable light sources (lanterns, torches etc.). \end{itemize} -This is probably enough to create around 90\% string filters you will eventually need. However, this expression is even more powerful -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: ``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? -\\ -Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned ``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers.\\ +This is probably enough to create around 90 string filters you will eventually need. However, this expression is even more powerful +-- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched +by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: +``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. +There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? -Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, you will clearly need way to determinate what letters you want to match (word is composed by letters).\\ +Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression +that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned +``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. -Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence Beginning with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It does not matter what is in between, because ''.*`` is used.\\ +Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: +when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular +expression is to use set of rules that will match to many words. It is not that difficult to see what it's needed to do so: first, +you will clearly need way to determinate what letters you want to match (word is composed by letters). -You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when ``[|]'' comes in handy. If you write something like: ``\^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either ``a'' or ``k''. Using ``\^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''.\\ +Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. +You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, +while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence beginning +with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It does not matter what is in between, +because ''.*`` is used.\\ -And What if you want to match more than just one latter? Just use ``(|)``. it is pretty similar to the above one letter as you see, but it is used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``.\\ +You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when +``[|]'' comes in handy. If you write something like: ``\^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either +``a'' or ``k''. Using ``\^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''. -Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure.\\ +What if you want to match more than just one latter? Just use ``(|)``. it is pretty similar to the above one letter as you see, but it is +used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences +starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``. + +Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on +Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure. \paragraph{Value -- value(``value'', (``open'', ``close''))} -While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like ``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range.\\ +While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like +``weight``. To filter those we need a value expression. This one works in similar manner to the string filter: first token name and criteria +inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range. As you would imagine the range can be specified as including a border value, or excluding. We are using two types of brackets for this: \begin{itemize} \item To include value use [] brackets. For value equal 5, expression value(something, [5, 10]) will evaluate to true. \item To exclude value use () brackets. For value equal 5, expression value(something, (5, 10)) will evaluate to false. - \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression will evaluate to false for value equal 10. + \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression + will evaluate to false for value equal 10. \end{itemize} \paragraph{''true`` and ''false``} -Nullary ''true`` and ''false`` do not accept any arguments, and always evaluates to true (in case of ''true``) and false (in case of ''false``) no matter what. The main usage of this expressions is the give users ability to quickly disable some part of the filter that makes heavy use of the logical expressions. +Nullary \textit{true} and \textit{false} do not accept any arguments, and always evaluates to true (in case of \textit{true}) +and false (in case of \textit{false}) no matter what. The main usage of this expressions is the give users ability to quickly +disable some part of the filter that makes heavy use of the logical expressions. \subsubsection{Logical expressions} -This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical not, while the remaining binary expressions are: or, and. This clearly makes them (from the user point of view) belonging to the same group of logical expressions. +This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical +\textit{not}, while the remaining binary expressions are: \textit{or}, \textit{and}. This clearly makes them (from the user point of view) +belonging to the same group of logical expressions. \paragraph{not -- not expression()} -Sometimes you may be in need of reversing the output of the expression. This is where not comes in handy. Adding not before expression will revert it: if expression was returning true, it will return false; if it was returning false, it will return true. Brackets are not needed: not will revert only the first expression following it.\\ -To show this on know example, let's consider the ''string("armor type", ".* gauntlet"))`` filter. As We mentioned earlier this will return true for every gauntlet found in game. In order to show everything, but gauntlets we simply do ''not string("armor type", ".* gauntlet"))``. This is probably not the most useful filter on earth, but this is not a surprise: real value of not expression shines when combined with or, and filter. +Sometimes you may be in need of reversing the output of the expression. This is where \textit{not} comes in handy. Adding \textit{not} before +expression will revert it: if expression was returning true, it will return false; if it was returning false, it will return true. Brackets +are not needed: \textit{not} will revert only the first expression following it. + +To show this on know example, let's consider the ''string("armor type", ".* gauntlet"))`` filter. As we mentioned earlier this will return true +for every gauntlet found in game. In order to show everything, but gauntlets we simply do ''not string("armor type", ".* gauntlet"))``. +This is probably not the most useful filter on earth, but this is not a surprise: real value of \textit{not} expression shines when combined with +\textit{or}, \textit{and} filters. \paragraph{or -- or(expression1(), expression2())} -Or is a expression that will return true if one of the arguments evaluates to true. You can use two or more arguments, separated by the comma.\\ -Or expression is useful when showing two different group of records is needed. For instance the standard actor filter is using the following ''or(string(``record type'', npc), string(``record type'', creature))`` and will show both npcs and creatures. +\textit{Or} is a expression that will return true if one of the arguments evaluates to true. You can use two or more arguments, separated by the comma. + +\textit{Or} expression is useful when showing two different group of records is needed. For instance the standard actor filter is using the following +''or(string(``record type'', npc), string(``record type'', creature))`` and will show both npcs and creatures. \paragraph{and -- and(expression1(), expression2())} -And is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by a comma.\\ -As We mentioned earlier in the ''not`` filter, combining ''not`` with ''and`` can be very useful. For instance to show all armor types, excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. +\textit{And} is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, +separated by a comma. +As we mentioned earlier in the \textit{not} filter, combining \textit{not} with \textit{and} can be very useful. For instance to show all armor types, +excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. \subsubsection{Creating and saving filter} -In order to create and save new filter, you should go to the filters table, right click and select option ``add record'' from the context menu. A horizontal widget group at the bottom of the table should show up. From there you should select a namespace responsible for scope of the filter (described earlier) and desired ID of the filter. After pressing ok button new entry will show up in the filters table. This filter does nothing at the moment, since it still lacks expressions. In order to add your formula simply double click the filter cell of the new entry and write it down there.\\ +In order to create and save new filter, you should go to the filters table, right click and select option ``add record'' from the context menu. +A horizontal widget group at the bottom of the table should show up. From there you should select a namespace responsible for scope of +the filter (described earlier) and desired ID of the filter. After pressing OK button new entry will show up in the filters table. This filter +does nothing at the moment, since it still lacks expressions. In order to add your formula simply double click the filter cell of the new entry +and write it down there. Done! You are free to use your filter. \subsubsection{Replacing the default filters set} -{OpenCS} allows you to substitute default filters set provided by us, with your own filters. In order to do so you should create a new project, add desired filters, remove undesired and save. Rename the file to the ``defaultfilters'' (don't forget to remove .omwaddon.project extension) and place it inside your configuration directory.\\ -The file acts as template for all new project files from now. If you wish to go back to the old default set, simply rename or remove the custom file. \ No newline at end of file +{OpenCS} allows you to substitute default filters set provided by us, with your own filters. In order to do so you should create a new project, +add desired filters, remove undesired and save. Rename the file to the ``defaultfilters'' (do not forget to remove .omwaddon.project extension) +and place it inside your configuration directory. + +The file acts as template for all new project files from now. If you wish to go back to the old default set, simply rename or remove the custom file. diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex index 577b7078b3..3a395e277d 100644 --- a/manual/opencs/main.tex +++ b/manual/opencs/main.tex @@ -1,8 +1,24 @@ \documentclass[american]{article} \usepackage[T1]{fontenc} \usepackage{babel} -\usepackage{graphicx} +\usepackage{txfonts} % Public Times New Roman text & math font +\usepackage[pdftex]{graphicx} +\usepackage[colorlinks,pdftex]{hyperref} \author{OpenMW Team} + +\def\pdfBorderAttrs{/Border [0 0 0] } % No border arround Links + +\def\CPP{{C\kern-.05em\raise.23ex\hbox{+\kern-.05em+}}} +\hypersetup{% + pdfauthor={Copyright \textcopyright{} OpenMW Team }, + pdftitle={OpenCS user manual} +} + +\def\MW{\textit{Morrowind\texttrademark{}\ }} +\def\TB{\textit{Tribunal\ }} +\def\BM{\textit{Bloodmon\ }} +\def\BS{Bethesda Softworks\ } + \begin{document} \title{OpenCS User Manual} diff --git a/manual/opencs/tables.tex b/manual/opencs/tables.tex index fb6d41ba8d..cbb59b2dd7 100644 --- a/manual/opencs/tables.tex +++ b/manual/opencs/tables.tex @@ -1,7 +1,11 @@ \section{Tables} \subsection{Introduction} -If you have launched OpenCS already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. You'd be spot on: OpenCS is built around using tables. This doesn't mean it works just like Excel or Calc, though. Due to the vast amounts of information involved with Morrowind, tables just made the most sense. You have to be able to spot information quickly and be able to change them on the fly. Let's browse through the various screens and see what all these tables show. +If you have launched OpenCS already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. +You'd be spot on: OpenCS is built around using tables. This does not mean it works just like Microsoft Excel or Libre Office Calc, though. +Due to the vast amounts of information involved with \MW, tables just made the most sense. You have to be able to spot information quickly +and be able to change them on the fly. +Let's browse through the various screens and see what all these tables show. \subsection{Used Terms} @@ -10,62 +14,87 @@ If you have launched OpenCS already and played around with it for a bit, you hav \begin{description} \item[Record:] An entry in OpenCS representing an item, location, sound, NPC or anything else. - \item[Reference, Referenceable:] When an item is placed in the world, it doesn't create a new record each time. For example, the game world might contain a lot of exquisite belts on different NPCs and in many crates, but they all refer to one specific record: the Exquisite Belt record. In this case, all those belts in crates and on NPCs are references. The central Exquisite Belt record is called a referenceable. This allows modders to make changes to all items of the same type. For example, if you want all exquisite belts to have 4000 enchantment points rather than 400, you will only need to change the referenceable Exquisite Belt rather than all exquisite belts references individually. + \item[Reference, Referenceable:] When an item is placed in the world, it does not create a new record each time. For example, the game world might + contain a lot of exquisite belts on different NPCs and in many crates, but they all refer to one specific record: the Exquisite Belt record. + In this case, all those belts in crates and on NPCs are references. The central Exquisite Belt record is called a referenceable. This allows modders + to make changes to all items of the same type. For example, if you want all exquisite belts to have 4000 enchantment points rather than 400, you will + only need to change the referenceable Exquisite Belt rather than all exquisite belts references individually. \end{description} \subsubsection{Recurring Terms} - Some columns are recurring throughout OpenCS. They show up in (nearly) every table in OpenCS. \begin{description} -\item[ID] Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. For example, the ID for the (unique) black pants of Caius Cosades is ``Caius\_pants''. This allows you to manipulate the game in many ways. For example, you could add these pants to your inventory by simply opening the console and write: ``player->addItem Caius\_pants''. Either way, in both Morrowind and OpenCS, the ID is the primary way to identify all these different parts of the game. %Wrong! Cells do not have ID, only name. +\item[ID] Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. +For example, the ID for the (unique) black pants of Caius Cosades is ``Caius\_pants''. This allows you to manipulate the game in many ways. For example, +you could add these pants to your inventory by simply opening the console and write: ``player->addItem Caius\_pants''. Either way, in both Morrowind +and OpenCS, the ID is the primary way to identify all these different parts of the game. %Wrong! Cells do not have ID, only name. \item[Modified] This column shows what has happened (if something has happened) to this record. There are four possible states in which it can exist. -\item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with optionally the Bloodmoon and Tribunal expansions. +\item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with +optionally the Bloodmoon and Tribunal expansions. \item[Added] means that this record was not in the base game and has been added by a modder. \item[Modified] means that the record is part of the base game, but has been changed in some way. -\item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences in the game itself have been removed! For example, if you remove the CharGen\_Bed entry from morrowind.esm, it doesn't mean the bedroll in the basement of the Census and Excise Office in Seyda Neen is gone. You're going to have to delete that reference yourself or make sure that that object is replaced by something that still exists otherwise you'll get crashes in the worst case scenario. - \end{description} +\item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences +in the game itself have been removed! For example, if you remove the CharGen\_Bed entry from morrowind.esm, it does not mean the bedroll in the basement +of the Census and Excise Office in Seyda Neen is gone. You're going to have to delete that reference yourself or make sure that that object is replaced +by something that still exists otherwise you will get crashes in the worst case scenario. +\end{description} \subsection{World Screens} - The contents of the game world can be changed by choosing one of the options in the appropriate menu at the top of the screen. \subsubsection{Regions} - This describes the general areas of Vvardenfell. Each of these areas has different rules about things such as encounters and weather. \begin{description} \item[Name:] This is how the game will show your location in-game. - \item[Map Colour:] This is a six-digit hexidecimal representation of the colour used to identify the region on the map available in World > Region Map. If you don't have an application with a colour picker, you can use your favourite search engine to find a colour picker online. + \item[Map Colour:] This is a six-digit hexidecimal representation of the colour used to identify the region on the map available in + World > Region Map. If you don't have an application with a colour picker, you can use your favourite search engine to find a colour picker online. \item[Sleep Encounter:] These are the rules for what kind of enemies you might encounter when you sleep outside in the wild. \end{description} \subsubsection{Cells} +Expansive worlds such as Vvardenfell, with all its items, NPCs, etc. have a lot going on simultaneously. But if you are in Balmora, +why would the computer need to keep track the exact locations of NPCs walking through the corridors in a Vivec canton? All that work would +be quite useless and bring your system to its knees! So the world has been divided up into squares we call "cells". Once your character enters a cell, +the game will load everything that is going on in that cell so you can interact with it. -Expansive worlds such as Vvardenfell, with all its items, NPCs, etc. have a lot going on simultaneously. But if you are in Balmora, why would the computer need to keep track the exact locations of NPCs walking through the corridors in a Vivec canton? All that work would be quite useless and bring your system to its knees! So the world has been divided up into squares we call "cells". Once your character enters a cell, the game will load everything that is going on in that cell so you can interact with it. - -In the original Morrowind this could be seen when you were travelling and you would see a small loading bar at the bottom of the screen; you had just entered a new cell and the game would have to load all the items and NPCs. The Cells screen in OpenCS provides you with a list of cells in the game, both the interior cells (houses, dungeons, mines, etc.) and the exterior cells (the outside world). +In the original \MW this could be seen when you were travelling and you would see a small loading bar at the bottom of the screen; +you had just entered a new cell and the game would have to load all the items and NPCs. The Cells screen in OpenCS provides you with a list of cells +in the game, both the interior cells (houses, dungeons, mines, etc.) and the exterior cells (the outside world). \begin{description} - \item[Sleep Forbidden:] Can the player sleep on the floor? In most cities it is forbidden to sleep outside. Sleeping in the wild carries its own risks of attack, though, and this entry lets you decide if a player should be allowed to sleep on the floor in this cell or not. + \item[Sleep Forbidden:] Can the player sleep on the floor? In most cities it is forbidden to sleep outside. Sleeping in the wild carries its + own risks of attack, though, and this entry lets you decide if a player should be allowed to sleep on the floor in this cell or not. - \item[Interior Water:] Should water be rendered in this interior cell? The game world consists of an endless ocean at height 0. Then the landscape is added. If part of the landscape goes below height 0, the player will see water. (See illustration.) + \item[Interior Water:] Should water be rendered in this interior cell? The game world consists of an endless ocean at height 0. Then the landscape + is added. If part of the landscape goes below height 0, the player will see water. (See illustration.) - Setting the cell's Interior Water to true tells the game that this cell is both an interior cell (inside a building, for example, rather than in the open air) but that there still needs to be water at height 0. This is useful for dungeons or mines that have water in them. + Setting the cell's Interior Water to true tells the game that this cell is both an interior cell (inside a building, for example, rather than + in the open air) but that there still needs to be water at height 0. This is useful for dungeons or mines that have water in them. - Setting the cell's Interior Water to false tells the game that the water at height 0 should not be used. Remember that cells that are in the outside world are exterior cells and should thus \textit{always} be set to false! + Setting the cell's Interior Water to false tells the game that the water at height 0 should not be used. Remember that cells that are in + the outside world are exterior cells and should thus \textit{always} be set to false! - \item[Interior Sky:] Should this interior cell have a sky? This is a rather unique case. The \textit{Tribunal} expansion took place in a city on the mainland. Normally this would require the city to be composed of exterior cells so it has a sky, weather and the like. But if the player is in an exterior cell and looks at his in-game map, he sees Vvardenfell with an overview of all exterior cells. The player would have to see the city's very own map, as if he was walking around in an interior cell. + \item[Interior Sky:] Should this interior cell have a sky? This is a rather unique case. The \TB expansion took place in a city on + the mainland. Normally this would require the city to be composed of exterior cells so it has a sky, weather and the like. But if the player is + in an exterior cell and looks at his in-game map, he sees Vvardenfell with an overview of all exterior cells. The player would have to see + the city's very own map, as if he was walking around in an interior cell. - So the developers decided to create a workaround and take a bit of both: The whole city would technically work exactly like an interior cell, but it would need a sky as if it was an exterior cell. That's what this is. This is why the vast majority of the cells you will find in this screen will have this option set to false: It's only meant for these "fake exteriors". + So the developers decided to create a workaround and take a bit of both: The whole city would technically work exactly like an interior cell, + but it would need a sky as if it was an exterior cell. That's what this is. This is why the vast majority of the cells you will find in this screen + will have this option set to false: It's only meant for these "fake exteriors". - \item[Region:] To which Region does this cell belong? This has an impact on the way the game handles weather and encounters in this area. It is also possible for a cell not to belong to any region. + \item[Region:] To which Region does this cell belong? This has an impact on the way the game handles weather and encounters in this area. + It is also possible for a cell not to belong to any region. \end{description} \subsubsection{Referenceables} - -This is a library of all the items, triggers, containers, NPCs, etc. in the game. There are several kinds of Record Types. Depending on which type a record is, it will need specific information to function. For example, an NPC needs a value attached to its aggression level. A chest, of course, does not. All Record Types contain at least a model. How else would the player see them? Usually they also have a Name, which is what you see when you hover your reticle over the object. +This is a library of all the items, triggers, containers, NPCs, etc. in the game. There are several kinds of Record Types. Depending on which type +a record is, it will need specific information to function. For example, an NPC needs a value attached to its aggression level. A chest, of course, +does not. All Record Types contain at least a model. How else would the player see them? Usually they also have a Name, which is what you see +when you hover your reticle over the object. Let's go through all Record Types and discuss what you can tell OpenCS about them. diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index 3bdfa63626..de377a119f 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -1,28 +1,53 @@ \section{Windows} \subsection{Introduction} -This section describes the multiple windows interface of the OpenCS editor. This design principle was chosen in order to extend the flexibility of the editor, especially on the multiple screens setups and on environments providing advanced windows management features, like; for instance; multiple desktops found commonly on many open source desktop environments. However, it is enough to have a single large screen to see the advantages of this concept.\\ -OpenCS windows interface is easy to describe and understand. In fact We decided to minimize use of many windows concepts applied commonly in various applications. For instance dialog windows are really hard to find in the OpenCS. You are free to try, though.\\ -Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly focused on practical ways of organizing work with the OpenCS. +This section describes the multiple windows interface of the OpenCS editor. This design principle was chosen in order +to extend the flexibility of the editor, especially on the multiple screens setups and on environments providing advanced +windows management features, like; for instance: multiple desktops found commonly on many open source desktop environments. +However, it is enough to have a single large screen to see the advantages of this concept. + +OpenCS windows interface is easy to describe and understand. In fact we decided to minimize use of many windows concepts +applied commonly in various applications. For instance dialog windows are really hard to find in the OpenCS. You are free to try, +though. + +Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly +focused on practical ways of organizing work with the OpenCS. \subsection{Basics} -After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: there is a menubar at the top, and there is a large empty area. That's it: a brand new Open{CS} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some panels\footnote{Also known as widgets.}. You are free to do so, just try to explore the menubar. \\ -You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's just focus on the windows itself. +After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: +there is a menubar at the top, and there is a large empty area. That is it: a brand new Open{CS} window contains only menubar +and statusbar. In order to make it a little bit more useful you probably want to enable some panels\footnote{Also known as widgets.}. +You are free to do so, just try to explore the menubar. + +You probably founded out the way to enable and disable some interesting tables, but those will be described later. For now, let's +just focus on the windows itself. \paragraph{Creating new windows} -is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, it is also blank, and you are free to add any of the Open{CS} panels. +is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, +it is also blank, and you are free to add any of the Open{CS} panels. \paragraph{Closing opened window} -is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. Closing last Open{CS} window will also terminate application session. +is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. +Closing last Open{CS} window will also terminate application session. \paragraph{Multi-everything} -is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with any panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and you are wonder if you are able to have one hundred Open{CS} windows showing panels of the same type, well most likely you are able to do so.\\ +is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with +any panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and +you are wonder if you are able to have one hundred Open{CS} windows showing panels of the same type, well most likely you are +able to do so. -The principle behind this design decision is easy to see for Bethesda made editor, but maybe not so clear for users who are just about to begin their wonderful journey of modding.\\ +The principle behind this design decision is easy to see for \BS made editor, but maybe not so clear for users who are +just about to begin their wonderful journey of modding. \subsection{Advanced} -So why? Why this is created in such manner. The answer is frankly simple: because it is effective. When creating a mod, you often have to work only with just one table. For instance you are just balancing weapons damage and other statistics. It makes sense to have all the space for just that one table. More often, you are required to work with two and switch them from time to time. All major graphical environments commonly present in operating systems comes with switcher feature, that is a key shortcut to change active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work with two at the time, and with one from time to time. Here, you can have one window holding two tables, and second holding just one.\\ +So why? Why this is created in such manner. The answer is frankly simple: because it is effective. When creating a mod, you often +have to work only with just one table. For instance you are just balancing weapons damage and other statistics. It makes sense +to have all the space for just that one table. More often, you are required to work with two and switch them from time to time. +All major graphical environments commonly present in operating systems comes with switcher feature, that is a key shortcut to change +active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work +with two at the time, and with one from time to time. Here, you can have one window holding two tables, and second holding just one. -Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one flexible approach in all cases.\\ +Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one +flexible approach in all cases. There is no point in digging deeper in the windows of Open{CS}. Let's explore panels, starting with tables. From 2e5e9e0c44c6ca16470396e6c3d0ee50b6a34e35 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 1 Dec 2013 01:15:46 +0100 Subject: [PATCH 35/56] Small official/unofficial style cleanup - missed that one. Signed-off-by: Lukasz Gromanowski --- manual/opencs/filters.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index e3781619c9..4eb0985a59 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -25,7 +25,7 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \end{description} \subsubsection{Basics} -In fact you don't need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity +In fact you do not need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity with OpenCS is inside basics section. \subsubsection{Interface} From 3b64de7441a65be7b02e4954fc8a09f1a108512b Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 1 Dec 2013 03:18:08 +0100 Subject: [PATCH 36/56] Another part of reformatting and clean up. Signed-off-by: Lukasz Gromanowski --- manual/opencs/files_and_directories.tex | 42 +++++----- manual/opencs/filters.tex | 106 ++++++++++++------------ manual/opencs/main.tex | 14 ++-- manual/opencs/tables.tex | 32 +++---- manual/opencs/windows.tex | 24 +++--- 5 files changed, 111 insertions(+), 107 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index ce686d56cb..b3283dac48 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -1,53 +1,53 @@ \section{Files and Directories} \subsection{Introduction} This section of the manual covers usage of files and directories by the OpenCS. Files and directories are file system concepts, -and you are probably already familiar with it. We won't try to explain this concepts, we will just focus on Open{CS}. +and you are probably already familiar with it. We won't try to explain this concepts, we will just focus on \OCS. \subsection{Used terms} %TODO \subsection{Basics} \paragraph{Directories} -Open{MW} and Open{CS} uses multiple directories on file systems. First of, there is a \textbf{user directory} that holds configuration +OpenMW and \OCS{} uses multiple directories on file systems. First of, there is a \textbf{user directory} that holds configuration files and few different folders. The location of the user directory is hard coded for each supported operating system. %TODO list paths. -In addition to this single hard coded directory, both Open{MW} and Open{CS} need a place to seek for actual data files of the game: +In addition to this single hard coded directory, both \OMW{} and \OCS{} need a~place to seek for actual data files of the game: textures, models, sounds and files that store records of objects in game; dialogues and so one -- so called content files. We support -multiple such paths (We call it \textbf{data paths}) as specified in the configuration. Usually one data path points to the directory -where original Morrowind\texttrademark is either installed or unpacked. You are free to specify as many data paths as you would like, +multiple such paths (we call it \textbf{data paths}) as specified in the configuration. Usually one data path points to the directory +where original \MW{} is either installed or unpacked. You are free to specify as many data paths as you would like, however, there is one special data path that, as described later, is used to store newly created content files. \paragraph{Content files} -\BS \MW engine is using two types of files: ESM (master) and ESP (plugin). The distinction between those +\BS{} \MW{} engine is using two types of files: ESM (master) and ESP (plugin). The distinction between those is not clear, and often confusing. You would expect the ESM (master) file is used to specify one master, that is modified by the ESPs plugins, and indeed: this is the basic idea. However, original expansions also were made as ESM files, even though they essentially could be described as a really large plugins, and therefore rather use ESP files. There were technical reasons behind this decision -- somewhat valid -in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. Open{MW} achieves +in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. \OMW{} achieves his with our own content file types. We support both ESM and ESP files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``. -\subparagraph{Open{MW} content files} +\subparagraph{OpenMW content files} Game and Addon files are concept somewhat similar to the old ESM/ESP, only in the way it should be from the very beginning. Nothing easier -to describe. If you want to make new game using Open{MW} as engine (so called ``total conversion'') you should create a game file. +to describe. If you want to make new game using \OMW{} as engine (so called ``total conversion'') you should create a game file. If you want to create a addon for existing game file -- simply create addon file. Nothing else matters: The only distinction you should consider is if your project is about changing other game, or creating a new one. Simple as that. Other simple thing about content files are extensions. We are using .omwaddon for addon files and .omwgame for game files. %TODO describe what content files contains. and what not. -\subparagraph{\MW content files} -Using our content files is recommended solution for projects that are intended to used with Open{MW} engine. However some players -wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, We are very +\subparagraph{\MW{} content files} +Using our content files is recommended solution for projects that are intended to used with \OMW{} engine. However some players +wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, we are very successful project. Yay!}. Also, since 2002 thousands of ESP/ESM files were created, some with really outstanding content. -Because of this Open{CS} simply has no other choice but support ESP/ESM files. However, if you decided to choose ESP/ESM file instead +Because of this \OCS{} simply has no other choice but support ESP/ESM files. However, if you decided to choose ESP/ESM file instead using our own content file types you are most likely aim at the original engine compatibility. This subject is covered in the very last section of this manual. %not finished TODO add the said section. Most likely when more features are present. The actual creation of new files is described in the next chapter. Here we are gonna focus only on details that you need to know -in order to create your first Open{CS} file while full understanding your needs. For now let's jut remember that content files +in order to create your first \OCS{} file while full understanding your needs. For now let's jut remember that content files are created inside the user directory, in the the \textbf{data} subfolder (that is the one special data directory mentioned earlier). \subparagraph{Dependencies} @@ -65,7 +65,7 @@ for addon files -- it can not depend on addon files. %\subparagraph{Loading order} %TODO \paragraph{Project files} -Project files act as containers for data not used by the Open{MW} game engine itself, but still useful for OpenCS. The shining example +Project files act as containers for data not used by the \OMW{} game engine itself, but still useful for OpenCS. The shining example of this data category are without doubt record filters (described in the later section of the manual you are reading currently). As a mod author you probably do not need and/or want to distribute project files at all, they are meant to be used only by you. @@ -76,12 +76,12 @@ with appended extensions. For instance swords.omwaddon file is associated with s %TODO where are they stored. Project files are stored inside the user directory, in the \textbf{projects} subfolder. This is the path location for both freshly -created project files, and a place where Open{CS} looks for already existing files. +created project files, and a place where \OCS{} looks for already existing files. \paragraph{Resources files} %textures, sounds, whatever Unless we are talking about the fully text based game, like Zork or Rogue, you are expecting that a video game is using some media files: -models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is ESP, ESM or new Open{MW} +models with textures, pictures acting as icons, sounds and everything else. Since content files, no matter if it is ESP, ESM or new \OMW{} file type do not contain any of those, it is clear that they have to be deliver with a different file. It is also clear that this, let's call it ``resources file``, have to be supported by the engine. Without code handling those files, it is nothing more than a mathematical abstraction -- something, that lacks meaning for human beings\footnote{Unless we call programmers a human beings.}. @@ -89,7 +89,7 @@ Therefore this section must cover ways to add resources files to your content fi to do just that. Later, you will learn how to make use of those files in your content. \subparagraph{Audio} -Open{MW} is using {FF}mpeg for audio playback, and so we support every audio type that is supported by this library. This makes a huge list. +OpenMW is using {FFmpeg} for audio playback, and so we support every audio type that is supported by this library. This makes a huge list. Below is only small portion of supported file types. \begin{description} @@ -102,16 +102,16 @@ As in the case of audio files, we are using {FFmepg} to decode video files. The only the most significant. \begin{description} - \item bik videos used by original Morrowind game. + \item bik videos used by original \MW{} game. \item mp4 multimedia container which use more advanced codecs (MPEG-4 Parts 2,3,10) with a better audio and video compression rate, but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, - but since game logic is not running during cut scenes we can recommended it for use with Open{MW}. + but since game logic is not running during cut scenes we can recommended it for use with \OMW. \item ogv alternative, open source container using theora codec for video and vorbis for audio. \end{description} \subparagraph{Textures and images} -Original \MW game uses DDS and TGA files for all kind of two dimensional images and textures alike. In addition, engine supported BMP +Original \MW{} game uses DDS and TGA files for all kind of two dimensional images and textures alike. In addition, engine supported BMP files for some reason (BMP is a terrible format for a video game). We also support extended set of image files -- including JPEG and PNG. JPEG and PNG files can be useful in some cases, for instance JPEG file is a valid option for skybox texture and PNG can useful for masks. However please, keep in mind that JPEG can grow into large sizes quickly and are not the best option with DirectX rendering backend. diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 4eb0985a59..802aa3ec5f 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -1,16 +1,16 @@ -\section{Record filters} +d\section{Record filters} \subsection{Introduction} -Filters are the key element of OpenCS use cases by allowing rapid and easy access to the searched records presented in all tables. +Filters are the key element of \OCS{} use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in the this section of the manual are perfectly clear to you. -Don't be afraid though, filters are fairly intuitive and easy to use. +Do not be afraid though, filters are fairly intuitive and easy to use. \subsubsection{Used Terms} \begin{description} \item[Filter] is generally speaking a tool able to ``Filter'' (that is: select some elements, while discarding others) according - to the some criteria. In case of OpenCS: records are being filtered according to the criteria of user choice. Criteria are written + to the some criteria. In case of \OCS: records are being filtered according to the criteria of user choice. Criteria are written down in language with simple syntax. \item[Criteria] describes condition under with any any record is being select by the filter. \item[Syntax] as you may noticed computers (in general) are rather strict, and expect only strictly formulated orders -- that is: @@ -18,20 +18,20 @@ Don't be afraid though, filters are fairly intuitive and easy to use. \item[Expression] is way we are actually performing filtering. Filter can be treated as ``functions'': accepts arguments, and evaluates either to the true or false for every column record at the time. \item[N-ary] is any expression that expects one or more expressions as arguments. It is useful for grouping two (or more) other expressions - together in order to create filter that will check for criteria placed in two (again: or more) columns (logical ``or'', ``and''). - \item[unary] is any expression that expects one other expression. The example is ``not'' expression. In fact ``not'' is the only useful - unary expression in OpenCS record filters. + together in order to create filter that will check for criteria placed in two (again: or more) columns (logical \textit{or}, \textit{and}). + \item[unary] is any expression that expects one other expression. The example is \textit{not} expression. In fact \textit{not} is the only useful + unary expression in \OCS{} record filters. \item[nullary] is expression that does not accepts other expressions. It accepts arguments specified later. \end{description} \subsubsection{Basics} In fact you do not need to learn everything about filters in order to use them. In fact all you need to know to achieve decent productivity -with OpenCS is inside basics section. +with \OCS{} is inside basics section. \subsubsection{Interface} -Above each table there is a field that is used to enter filter: either predefined by the OpenMW developers or made by you, the user. +Above each table there is a field that is used to enter filter: either predefined by the \OMW{} developers or made by you, the user. You probably noticed it before. However there is also completely new element, although using familiar table layout. Go to the application -menu view, and click filters. You should see set of default filters, made by the OpenMW team in the table with the following columns: filter, +menu view, and click filters. You should see set of default filters, made by the \OMW{} team in the table with the following columns: filter, description and modified. \begin{description} @@ -44,20 +44,21 @@ description and modified. So let's learn how to actually use those to speed up your work. \subsubsection{Using predefined filters} Using those filters is quite easy and involves typing inside the filter field above the table. For instance, try to open referencables -table and type in the filters field the following: ``project::weapons''. As soon as you complete the text, table will magicly alter -and will show only the weapons. As you could noticed project::weapons is nothing else than a ID of one of the predefined filters. That is it: +table and type in the filters field the following: \mono{project::weapons}. As soon as you complete the text, table will magicly alter +and will show only the weapons. As you could noticed \mono{project::weapons} is nothing else than a~ID of one of the predefined filters. That is it: in order to use the filter inside the table you simply type it is name inside the filter field. To make life easier filter IDs follow simple convention. \begin{itemize} - \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance project::weapons filter + \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance \mono{project::weapons} filter contains the word weapons (did you noticed?). Plural form is always used. \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance project::weaponssilver will - filter only silver weapons (new mechanic introduced by the Bloodmoon, silver weapons deal double damage against werewolfs) and - project::weaponsmagical will filter only magical weapons (able to hurt ghosts and other supernatural creatures). - \item There are few exceptions from the above rule. For instance there is a project::added, project::removed, project::modyfied, project::base. - You would probably except something more like ``project::statusadded'' but in this case typing this few extra characters would only + filter only silver weapons (new mechanic introduced by the \BM{}, silver weapons deal double damage against werewolfs) and + \mono{project::weaponsmagical} will filter only magical weapons (able to hurt ghosts and other supernatural creatures). + \item There are few exceptions from the above rule. For instance there is a \mono{project::added}, \mono{project::removed}, + \mono{project::modyfied}, \mono{project::base}. + You would probably except something more like \mono{project::statusadded} but in this case typing this few extra characters would only help to break your keyboard faster. \end{itemize} @@ -71,13 +72,13 @@ Finally, you will have to write this with correct syntax. As a result table will Advance subsection covers everything that you need to know in order to create any filter you may want to %TODO the filter part is actually wrong \subsubsection{Namespaces} -Did you noticed that every default filter has ``project::`` prefix? It is a ``namespace``, a term borrowed from the \CPP{} language. -In case of OpenCS namespace always means scope of the said object\footnote{You are not supposed to understand this at the moment.}. +Did you noticed that every default filter has \mono{project::} prefix? It is a \textit{namespace}, a~term borrowed from the \CPP{} language. +In case of \OCS{} namespace always means scope of the said object\footnote{You are not supposed to understand this at the moment.}. But what does it mean in case of filters? Well, short explanation is actually simple. \begin{description} - \item[project::] namespace indicates that filter is used with the project, in multiple sessions. You can restart Open{CS} and filter + \item[project::] namespace indicates that filter is used with the project, in multiple sessions. You can restart \OCS{} and filter is still there. - \item[session::] namespace indicates that filter is not stored trough multiple sessions and once you will quit Open{CS} (close session) + \item[session::] namespace indicates that filter is not stored trough multiple sessions and once you will quit \OCS{} (close session) the filter will be gone. Forever! Until then it can be found inside the filters table. \end{description} In addition to this two scopes, there is a third one; called one-shot. One-shot filters are not stored (even during single session) @@ -89,8 +90,8 @@ Still, you may wonder how you are supposed to write expressions, what expression with nullary expressions that will allow you to create a basic filter. \subsubsection{Nullary expressions} -All nullary expressions are used in similar manner. First off: you have to write it is name (for instance: ``string'') and secondly: -condition that will be checked inside brackets (for instance string(something, something)). If conditions of your expression will be meet +All nullary expressions are used in similar manner. First off: you have to write it is name (for instance: \mono{string}) and secondly: +condition that will be checked inside brackets (for instance \mono{string(something, something)}). If conditions of your expression will be meet by a record (technical speaking: expression will evaluate to true) the record will show up in the table. It is clear that you need to know what are you checking, that is: what column of the table contains information that you are interested @@ -99,27 +100,27 @@ you want to see, while the second one sets desired value inside of the cell. To \paragraph{String -- string(``column'', ``value'')} String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} -just a word for anything composed of characters. In case of OpenCS this is in fact true for every value inside the column that is not composed -of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression. -\footnote{There is no Boolean (''true'' or ``false'') value in the OpenCS. You should use string for those.} String evaluates to true, +just a word for anything composed of characters. In case of \OCS{} this is in fact true for every value inside the column that is not composed +of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression\footnote{There is no +Boolean (''true'' or ``false'') value in the \OCS. You should use string for those.}. String evaluates to true, when record contains in the specified column exactly the same value as specified. Since majority of the columns contain string values, string is among the most often used expressions. Examples: \begin{itemize} - \item string(``Record Type'', ``Weapon'') -- will evaluate to true for all records containing ``Weapon'' in the ``Record Type'' column cell. + \item \mono{string(``Record Type'', ``Weapon'')} -- will evaluate to true for all records containing \mono{Weapon} in the \mono{Record Type} column cell. This group contains every weapon (including arrows and bolts) found in the game. - \item string(``Portable'', ``true'') -- will evaluate to true for all records containing word true inside ``Portable'' column cell. + \item \mono{string(``Portable'', ``true'')} -- will evaluate to true for all records containing word true inside \mono{Portable} column cell. This group contains every portable light sources (lanterns, torches etc.). \end{itemize} This is probably enough to create around 90 string filters you will eventually need. However, this expression is even more powerful -- it accepts regular expressions (also called regexps). Regular expressions is a way to create string criteria that will be matched by one than just one specific value in the column. For instance, you can display both left and right gauntlets with the following expression: -``string("armor type", ".* gauntlet"))`` because ''.*'' in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. +\mono{string("armor type", ".* gauntlet"))} because \mono{.*} in regexps means just: ``anything''. This filter says: please, show me ``any'' gauntlet. There are left and right gauntlets in the morrowind so this will evaluate to true for both. Simple, isn't it? -Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, We are under impression +Creating regexps can be a difficult and annoying -- especially when you need complex criteria. On the other hand, we are under impression that in reality complex expressions are needed only in sporadic cases. In fact, the truth is: that most of the time only already mentioned -``.*'' is needed and therefore the following description of regexps can be skipped by vast majority of readers. +\mono{.*} is needed and therefore the following description of regexps can be skipped by vast majority of readers. Before working with Regular Expressions, you should understand what actually are regular expressions. Essentially, the idea is simple: when you are writing any word, you are using strictly defined letters -- that is: letters create a word. What you want to do with regular @@ -127,21 +128,22 @@ expression is to use set of rules that will match to many words. It is not that you will clearly need way to determinate what letters you want to match (word is composed by letters). Before introducing other ways to choose between characters, I want explain anchors. Anchors allows you to decide where to ``look'' in the string. -You surely should know about ``\^'' anchor and ``\textdollar''. Putting ``\^`` will tell to Open{CS} to look on the beginning of string, -while ''\textdollar`` is used to mark the end of it. For instance, pattern ''\^Pink.* elephant.\textdollar`` Will match any sentence beginning -with the word ''Pink`` and ending with '' elephant.``. Pink fat elephant. Pink cute elephant. It does not matter what is in between, -because ''.*`` is used.\\ +You surely should know about \mono{\textasciicircum} anchor and \mono{\textdollar}. Putting \mono{\textasciicircum} will tell to \OCS{} +to look on the beginning of string, while \mono{\textdollar} is used to mark the end of it. For instance, pattern +\mono{\textasciicircum{}Pink.* elephant.\textdollar} will match any sentence beginning with the word \mono{Pink} and ending with +\mono{ elephant.}. Pink fat elephant. Pink cute elephant. It does not matter what is in between, because \mono{.*} is used. -You have already seen the power of the simple ``.*''. But what if you want to chose between only two (or more) letters? Well, this is when -``[|]'' comes in handy. If you write something like: ``\^[a|k].*'' you are simply telling Open{CS} to filter anything that starts with either -``a'' or ``k''. Using ``\^[a|k|l].*'' will work in the same manner, but it will also cover strings starting with ``l''. +You have already seen the power of the simple \mono{.*}. But what if you want to chose between only two (or more) letters? Well, this is when +\mono{[|]} comes in handy. If you write something like: \mono{\textasciicircum[a|k].*} you are simply telling \OCS{} to filter anything that +starts with either \mono{a} or \mono{k}. Using \mono{\textasciicircum[a|k|l].*} will work in the same manner, but it will also cover +strings starting with \mono{l}. -What if you want to match more than just one latter? Just use ``(|)``. it is pretty similar to the above one letter as you see, but it is -used to fit more than just one character. For instance: ''\^(Pink|Green).* (elephant|crocodile).\textdollar`` will be true for all sentences -starting with ''Pink`` or ''Green`` and ending with either ''elephant.`` or ''crocodile.``. +What if you want to match more than just one latter? Just use \mono{(|)}. it is pretty similar to the above one letter as you see, but it is +used to fit more than just one character. For instance: \mono{\textasciicircum(Pink|Green).* (elephant|crocodile).\textdollar} will be +true for all sentences starting with \mono{Pink} or \mono{Green} and ending with either \mono{elephant.} or \mono{crocodile.}. Regular expressions are not the main topic of this manual. If you wish to learn more on this subject please, read the documentation on -Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use Open{CS} effectively to be sure. +Qt regular expressions syntax, or TRE regexp syntax (it is almost like in Qt). Above is just enough to use \OCS{} effectively to be sure. \paragraph{Value -- value(``value'', (``open'', ``close''))} While string expression covers vast group of columns containing string values, there are in fact columns with just numerical values like @@ -149,10 +151,10 @@ While string expression covers vast group of columns containing string values, t inside brackets. Clearly, conditions should hold column to test in. However in this case wanted value is specified as a range. As you would imagine the range can be specified as including a border value, or excluding. We are using two types of brackets for this: \begin{itemize} - \item To include value use [] brackets. For value equal 5, expression value(something, [5, 10]) will evaluate to true. - \item To exclude value use () brackets. For value equal 5, expression value(something, (5, 10)) will evaluate to false. - \item Mixing brackets is completely legal. For value equal 10, expression value(something, [5, 10) will evaluate to true. The same expression - will evaluate to false for value equal 10. + \item To include value use [] brackets. For value equal 5, expression \mono{value(something, [5, 10])} will evaluate to true. + \item To exclude value use () brackets. For value equal 5, expression \mono{value(something, (5, 10))} will evaluate to false. + \item Mixing brackets is completely legal. For value equal 10, expression \mono{value(something, [5, 10)} will evaluate to true. + The same expression will evaluate to false for value equal 10. \end{itemize} \paragraph{''true`` and ''false``} @@ -161,7 +163,7 @@ and false (in case of \textit{false}) no matter what. The main usage of this ex disable some part of the filter that makes heavy use of the logical expressions. \subsubsection{Logical expressions} -This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the OpenCS is logical +This subsection takes care of two remaining groups of expressions: binary and unary. The only unary expression present in the \OCS{} is logical \textit{not}, while the remaining binary expressions are: \textit{or}, \textit{and}. This clearly makes them (from the user point of view) belonging to the same group of logical expressions. @@ -170,8 +172,8 @@ Sometimes you may be in need of reversing the output of the expression. This is expression will revert it: if expression was returning true, it will return false; if it was returning false, it will return true. Brackets are not needed: \textit{not} will revert only the first expression following it. -To show this on know example, let's consider the ''string("armor type", ".* gauntlet"))`` filter. As we mentioned earlier this will return true -for every gauntlet found in game. In order to show everything, but gauntlets we simply do ''not string("armor type", ".* gauntlet"))``. +To show this on know example, let's consider the \mono{string("armor type", ".* gauntlet"))} filter. As we mentioned earlier this will return true +for every gauntlet found in game. In order to show everything, but gauntlets we simply do \mono{not string("armor type", ".* gauntlet"))}. This is probably not the most useful filter on earth, but this is not a surprise: real value of \textit{not} expression shines when combined with \textit{or}, \textit{and} filters. @@ -179,13 +181,13 @@ This is probably not the most useful filter on earth, but this is not a surprise \textit{Or} is a expression that will return true if one of the arguments evaluates to true. You can use two or more arguments, separated by the comma. \textit{Or} expression is useful when showing two different group of records is needed. For instance the standard actor filter is using the following -''or(string(``record type'', npc), string(``record type'', creature))`` and will show both npcs and creatures. +\mono{or(string(``record type'', npc), string(``record type'', creature))} and will show both npcs and creatures. \paragraph{and -- and(expression1(), expression2())} \textit{And} is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, separated by a comma. As we mentioned earlier in the \textit{not} filter, combining \textit{not} with \textit{and} can be very useful. For instance to show all armor types, -excluding gauntlets you can write the following: ''and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))''. +excluding gauntlets you can write the following: \mono{and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))}. \subsubsection{Creating and saving filter} In order to create and save new filter, you should go to the filters table, right click and select option ``add record'' from the context menu. @@ -196,7 +198,7 @@ and write it down there. Done! You are free to use your filter. \subsubsection{Replacing the default filters set} -{OpenCS} allows you to substitute default filters set provided by us, with your own filters. In order to do so you should create a new project, +OpenCS allows you to substitute default filters set provided by us, with your own filters. In order to do so you should create a new project, add desired filters, remove undesired and save. Rename the file to the ``defaultfilters'' (do not forget to remove .omwaddon.project extension) and place it inside your configuration directory. diff --git a/manual/opencs/main.tex b/manual/opencs/main.tex index 3a395e277d..1d8aebe408 100644 --- a/manual/opencs/main.tex +++ b/manual/opencs/main.tex @@ -3,7 +3,7 @@ \usepackage{babel} \usepackage{txfonts} % Public Times New Roman text & math font \usepackage[pdftex]{graphicx} -\usepackage[colorlinks,pdftex]{hyperref} +\usepackage[final,colorlinks,pdftex,pdfpagelabels=true]{hyperref} \author{OpenMW Team} \def\pdfBorderAttrs{/Border [0 0 0] } % No border arround Links @@ -13,11 +13,13 @@ pdfauthor={Copyright \textcopyright{} OpenMW Team }, pdftitle={OpenCS user manual} } - -\def\MW{\textit{Morrowind\texttrademark{}\ }} -\def\TB{\textit{Tribunal\ }} -\def\BM{\textit{Bloodmon\ }} -\def\BS{Bethesda Softworks\ } +\def\mono{\texttt} +\def\MW{\textit{Morrowind\texttrademark{}}} +\def\TB{\textit{Tribunal}} +\def\BM{\textit{Bloodmon}} +\def\BS{Bethesda Softworks} +\def\OMW{\hbox{OpenMW}} +\def\OCS{\hbox{OpenCS}} \begin{document} diff --git a/manual/opencs/tables.tex b/manual/opencs/tables.tex index cbb59b2dd7..e7cc06735a 100644 --- a/manual/opencs/tables.tex +++ b/manual/opencs/tables.tex @@ -1,8 +1,8 @@ \section{Tables} \subsection{Introduction} -If you have launched OpenCS already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. -You'd be spot on: OpenCS is built around using tables. This does not mean it works just like Microsoft Excel or Libre Office Calc, though. +If you have launched \OCS{} already and played around with it for a bit, you have probably gotten the impression that it contains lots of tables. +You'd be spot on: \OCS{} is built around using tables. This does not mean it works just like Microsoft Excel or Libre Office Calc, though. Due to the vast amounts of information involved with \MW, tables just made the most sense. You have to be able to spot information quickly and be able to change them on the fly. Let's browse through the various screens and see what all these tables show. @@ -12,7 +12,7 @@ Let's browse through the various screens and see what all these tables show. \subsubsection{Glossary} \begin{description} - \item[Record:] An entry in OpenCS representing an item, location, sound, NPC or anything else. + \item[Record:] An entry in \OCS{} representing an item, location, sound, NPC or anything else. \item[Reference, Referenceable:] When an item is placed in the world, it does not create a new record each time. For example, the game world might contain a lot of exquisite belts on different NPCs and in many crates, but they all refer to one specific record: the Exquisite Belt record. @@ -22,17 +22,17 @@ Let's browse through the various screens and see what all these tables show. \end{description} \subsubsection{Recurring Terms} -Some columns are recurring throughout OpenCS. They show up in (nearly) every table in OpenCS. +Some columns are recurring throughout \OCS. They show up in (nearly) every table in \OCS. \begin{description} -\item[ID] Each item, location, sound, etc. gets the same unique identifier in both OpenCS and Morrowind. This is usually a very self-explanatory name. +\item[ID] Each item, location, sound, etc. gets the same unique identifier in both \OCS{} and \MW. This is usually a very self-explanatory name. For example, the ID for the (unique) black pants of Caius Cosades is ``Caius\_pants''. This allows you to manipulate the game in many ways. For example, you could add these pants to your inventory by simply opening the console and write: ``player->addItem Caius\_pants''. Either way, in both Morrowind -and OpenCS, the ID is the primary way to identify all these different parts of the game. %Wrong! Cells do not have ID, only name. +and \OCS, the ID is the primary way to identify all these different parts of the game. %Wrong! Cells do not have ID, only name. \item[Modified] This column shows what has happened (if something has happened) to this record. There are four possible states in which it can exist. \item[Base] means that this record is part of the base game and is in its original state. Usually, if you create a mod, the base game is Morrowind with optionally the Bloodmoon and Tribunal expansions. -\item[Added] means that this record was not in the base game and has been added by a modder. +\item[Added] means that this record was not in the base game and has been added by a~modder. \item[Modified] means that the record is part of the base game, but has been changed in some way. \item[Deleted] means that this record used to be part of the base game, but has been removed as an entry. This does not mean, however, that the occurrences in the game itself have been removed! For example, if you remove the CharGen\_Bed entry from morrowind.esm, it does not mean the bedroll in the basement @@ -49,7 +49,7 @@ This describes the general areas of Vvardenfell. Each of these areas has differe \begin{description} \item[Name:] This is how the game will show your location in-game. \item[Map Colour:] This is a six-digit hexidecimal representation of the colour used to identify the region on the map available in - World > Region Map. If you don't have an application with a colour picker, you can use your favourite search engine to find a colour picker online. + World > Region Map. If you do not have an application with a colour picker, you can use your favourite search engine to find a colour picker online. \item[Sleep Encounter:] These are the rules for what kind of enemies you might encounter when you sleep outside in the wild. \end{description} @@ -59,8 +59,8 @@ why would the computer need to keep track the exact locations of NPCs walking th be quite useless and bring your system to its knees! So the world has been divided up into squares we call "cells". Once your character enters a cell, the game will load everything that is going on in that cell so you can interact with it. -In the original \MW this could be seen when you were travelling and you would see a small loading bar at the bottom of the screen; -you had just entered a new cell and the game would have to load all the items and NPCs. The Cells screen in OpenCS provides you with a list of cells +In the original \MW{} this could be seen when you were travelling and you would see a small loading bar at the bottom of the screen; +you had just entered a new cell and the game would have to load all the items and NPCs. The Cells screen in \OCS{} provides you with a list of cells in the game, both the interior cells (houses, dungeons, mines, etc.) and the exterior cells (the outside world). \begin{description} @@ -76,14 +76,14 @@ in the game, both the interior cells (houses, dungeons, mines, etc.) and the ext Setting the cell's Interior Water to false tells the game that the water at height 0 should not be used. Remember that cells that are in the outside world are exterior cells and should thus \textit{always} be set to false! - \item[Interior Sky:] Should this interior cell have a sky? This is a rather unique case. The \TB expansion took place in a city on + \item[Interior Sky:] Should this interior cell have a sky? This is a rather unique case. The \TB{} expansion took place in a city on the mainland. Normally this would require the city to be composed of exterior cells so it has a sky, weather and the like. But if the player is in an exterior cell and looks at his in-game map, he sees Vvardenfell with an overview of all exterior cells. The player would have to see the city's very own map, as if he was walking around in an interior cell. So the developers decided to create a workaround and take a bit of both: The whole city would technically work exactly like an interior cell, - but it would need a sky as if it was an exterior cell. That's what this is. This is why the vast majority of the cells you will find in this screen - will have this option set to false: It's only meant for these "fake exteriors". + but it would need a sky as if it was an exterior cell. That is what this is. This is why the vast majority of the cells you will find in this screen + will have this option set to false: It is only meant for these "fake exteriors". \item[Region:] To which Region does this cell belong? This has an impact on the way the game handles weather and encounters in this area. It is also possible for a cell not to belong to any region. @@ -93,11 +93,11 @@ in the game, both the interior cells (houses, dungeons, mines, etc.) and the ext \subsubsection{Referenceables} This is a library of all the items, triggers, containers, NPCs, etc. in the game. There are several kinds of Record Types. Depending on which type a record is, it will need specific information to function. For example, an NPC needs a value attached to its aggression level. A chest, of course, -does not. All Record Types contain at least a model. How else would the player see them? Usually they also have a Name, which is what you see +does not. All Record Types contain at least a~model. How else would the player see them? Usually they also have a Name, which is what you see when you hover your reticle over the object. -Let's go through all Record Types and discuss what you can tell OpenCS about them. +Let's go through all Record Types and discuss what you can tell \OCS{} about them. \begin{description} - \item[Activator:] This is an item that, when activated, starts a script or even just shows a tooltip. + \item[Activator:] This is an item that, when activated, starts a script or even just shows a~tooltip. \end{description} \ No newline at end of file diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index de377a119f..98bf369e85 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -1,20 +1,20 @@ \section{Windows} \subsection{Introduction} -This section describes the multiple windows interface of the OpenCS editor. This design principle was chosen in order +This section describes the multiple windows interface of the \OCS{} editor. This design principle was chosen in order to extend the flexibility of the editor, especially on the multiple screens setups and on environments providing advanced windows management features, like; for instance: multiple desktops found commonly on many open source desktop environments. However, it is enough to have a single large screen to see the advantages of this concept. OpenCS windows interface is easy to describe and understand. In fact we decided to minimize use of many windows concepts -applied commonly in various applications. For instance dialog windows are really hard to find in the OpenCS. You are free to try, +applied commonly in various applications. For instance dialog windows are really hard to find in the \OCS. You are free to try, though. Because of this, and the fact that we expect that user is familiar with other applications using windows this section is mostly -focused on practical ways of organizing work with the OpenCS. +focused on practical ways of organizing work with the \OCS. \subsection{Basics} -After starting Open{CS} and choosing content files to use a editor window should show up. It probably does not look surprising: -there is a menubar at the top, and there is a large empty area. That is it: a brand new Open{CS} window contains only menubar +After starting \OCS{} and choosing content files to use a editor window should show up. It probably does not look surprising: +there is a menubar at the top, and there is a~large empty area. That is it: a brand new \OCS{} window contains only menubar and statusbar. In order to make it a little bit more useful you probably want to enable some panels\footnote{Also known as widgets.}. You are free to do so, just try to explore the menubar. @@ -23,19 +23,19 @@ just focus on the windows itself. \paragraph{Creating new windows} is easy! Just visit view menu, and use the ``New View'' item. Suddenly, out of the blue a new window will show up. As you would expect, -it is also blank, and you are free to add any of the Open{CS} panels. +it is also blank, and you are free to add any of the \OCS{} panels. \paragraph{Closing opened window} is also easy! Simply close that window decoration button. We suspect that you knew that already, but better to be sure. -Closing last Open{CS} window will also terminate application session. +Closing last \OCS{} window will also terminate application session. \paragraph{Multi-everything} -is the main foundation of Open{CS} interface. You are free to create as many windows as you want to, free to populate it with +is the main foundation of \OCS{} interface. You are free to create as many windows as you want to, free to populate it with any panels you may want to, and move everything as you wish to -- even if it makes no sense at all. If you just got crazy idea and -you are wonder if you are able to have one hundred Open{CS} windows showing panels of the same type, well most likely you are +you are wonder if you are able to have one hundred \OCS{} windows showing panels of the same type, well most likely you are able to do so. -The principle behind this design decision is easy to see for \BS made editor, but maybe not so clear for users who are +The principle behind this design decision is easy to see for \BS{} made editor, but maybe not so clear for users who are just about to begin their wonderful journey of modding. \subsection{Advanced} @@ -46,9 +46,9 @@ All major graphical environments commonly present in operating systems comes wit active window. It is very effective and fast when you have only two windows, each holding only one table. Sometimes you have to work with two at the time, and with one from time to time. Here, you can have one window holding two tables, and second holding just one. -Open{CS} is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one +OpenCS is designed to simply make sense and do not slowdown users. It is as simple as possible (but not simpler), and uses one flexible approach in all cases. -There is no point in digging deeper in the windows of Open{CS}. Let's explore panels, starting with tables. +There is no point in digging deeper in the windows of \OCS. Let's explore panels, starting with tables. %We should write some tips and tricks here. \ No newline at end of file From 586990848041801ce2962bdd5f6ceb740240ab92 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 1 Dec 2013 12:03:04 +0100 Subject: [PATCH 37/56] Another small cleanup - missed that in previous commits. Signed-off-by: Lukasz Gromanowski --- manual/opencs/files_and_directories.tex | 2 +- manual/opencs/filters.tex | 4 ++-- manual/opencs/windows.tex | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index b3283dac48..d13cfa7270 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -106,7 +106,7 @@ only the most significant. \item mp4 multimedia container which use more advanced codecs (MPEG-4 Parts 2,3,10) with a better audio and video compression rate, but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, - but since game logic is not running during cut scenes we can recommended it for use with \OMW. + but since game logic is not running during cut scenes we can recommend it for use with \OMW. \item ogv alternative, open source container using theora codec for video and vorbis for audio. \end{description} diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index 802aa3ec5f..a5f88aebba 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -1,4 +1,4 @@ -d\section{Record filters} +\section{Record filters} \subsection{Introduction} Filters are the key element of \OCS{} use cases by allowing rapid and easy access to the searched records presented in all tables. Therefore: in order to use this application fully effective you should make sure that all concepts and instructions written in @@ -53,7 +53,7 @@ To make life easier filter IDs follow simple convention. \begin{itemize} \item Filter ID filtering a specific record type contains usually the name of a specific group. For instance \mono{project::weapons} filter contains the word weapons (did you noticed?). Plural form is always used. - \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance project::weaponssilver will + \item When filtering specific subgroup the ID starts just like in the case of general filter. For instance \mono{project::weaponssilver} will filter only silver weapons (new mechanic introduced by the \BM{}, silver weapons deal double damage against werewolfs) and \mono{project::weaponsmagical} will filter only magical weapons (able to hurt ghosts and other supernatural creatures). \item There are few exceptions from the above rule. For instance there is a \mono{project::added}, \mono{project::removed}, diff --git a/manual/opencs/windows.tex b/manual/opencs/windows.tex index 98bf369e85..97bb75e792 100644 --- a/manual/opencs/windows.tex +++ b/manual/opencs/windows.tex @@ -2,7 +2,7 @@ \subsection{Introduction} This section describes the multiple windows interface of the \OCS{} editor. This design principle was chosen in order to extend the flexibility of the editor, especially on the multiple screens setups and on environments providing advanced -windows management features, like; for instance: multiple desktops found commonly on many open source desktop environments. +windows management features, like for instance: multiple desktops found commonly on many open source desktop environments. However, it is enough to have a single large screen to see the advantages of this concept. OpenCS windows interface is easy to describe and understand. In fact we decided to minimize use of many windows concepts From 8b74e8cba7da123119217d88fd7d18da627de826 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 1 Dec 2013 13:00:44 +0100 Subject: [PATCH 38/56] Commiting. Not sure what since i had short blackout :/ --- manual/opencs/creating_file.tex | 25 +++++++++++++++++++++++++ manual/opencs/files_and_directories.tex | 19 ++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/manual/opencs/creating_file.tex b/manual/opencs/creating_file.tex index e69de29bb2..8cab726174 100644 --- a/manual/opencs/creating_file.tex +++ b/manual/opencs/creating_file.tex @@ -0,0 +1,25 @@ +\section{OpenCS starting dialog} +\subsection{Introduction} +The great day has come. Today, you shall open \OCS{} application. And when you do this, you shall see our starting dialog window that holds three buttons +that can bring both pain and happiness. So just do this, please. + +\subsection{Basics} +Back to the manual? Great! As you can see, the starting window holds just three buttons. Since you are already familiar with our files system, they come +to you with no surprise.\\ + +First, there is a \textbf{Create A New Game} button. Clearly, you should press it when you want to create a game file. Than, what \textbf{Create A New Addon} button do? +Yes! You are right! This button will create any addon content file (and new project file associated with it)! Wonderful! And what the last remaining button do? \textbf{Edit A Content File}? Well, it comes with no surprise that this should be used when you need to alter existing content file, either a game or addon.\\ + +\paragraph{Selecting Files} +As We wrote earlier, + +\subsection{Advanced} +If you are paying attention, you noticed any extra icon with wrench. This one will open small settings window. Options here are few, and easy to list. +\begin{description} + \item {Window Size} is needed to configure initial window size of the starting window. + \item {Display format} can be used to configure behavior of the \OCS{} itself, however only in the limited degree. You can decide if you want \OCS{} to display icon, text or both in some columns of tables. +\end{description} + +%TODO configuration + +And that would be it. There is no point spending more time here. We should go forward now. \ No newline at end of file diff --git a/manual/opencs/files_and_directories.tex b/manual/opencs/files_and_directories.tex index b3283dac48..bb399ce991 100644 --- a/manual/opencs/files_and_directories.tex +++ b/manual/opencs/files_and_directories.tex @@ -24,7 +24,7 @@ is not clear, and often confusing. You would expect the ESM (master) file is use and indeed: this is the basic idea. However, original expansions also were made as ESM files, even though they essentially could be described as a really large plugins, and therefore rather use ESP files. There were technical reasons behind this decision -- somewhat valid in the case of original engine, but clearly it's better to create a system that can be used is more sensible way. \OMW{} achieves -his with our own content file types. +this with our own content file types. We support both ESM and ESP files, but in order to make use of new features of OpenMW one should consider using new file types designed with our engine in mind: game files and addon files together called ``content files``. @@ -40,7 +40,7 @@ Other simple thing about content files are extensions. We are using .omwaddon fo %TODO describe what content files contains. and what not. \subparagraph{\MW{} content files} Using our content files is recommended solution for projects that are intended to used with \OMW{} engine. However some players -wish to use original Morrowind engine, even with it large flaws and lacking features\footnote{If this is actually wrong, we are very +wish to use original \MW{} engine, even with it large flaws and lacking features\footnote{If this is actually wrong, we are very successful project. Yay!}. Also, since 2002 thousands of ESP/ESM files were created, some with really outstanding content. Because of this \OCS{} simply has no other choice but support ESP/ESM files. However, if you decided to choose ESP/ESM file instead using our own content file types you are most likely aim at the original engine compatibility. This subject is covered in the very @@ -60,7 +60,7 @@ this section of the manual does not cover creating the content files -- it is on keep in mind that dependencies exist, and is up to you what to decide if your content file should depend on other content file. Game files are not intend to have any dependencies for a very simple reasons: player is using only one game file (excluding original -and dirty ESP/ESM system) at the time and therefore no game file can depend on other game file, and since game file makes the base +and dirty {ESP/ESM} system) at the time and therefore no game file can depend on other game file, and since game file makes the base for addon files -- it can not depend on addon files. %\subparagraph{Loading order} %TODO @@ -93,7 +93,7 @@ OpenMW is using {FFmpeg} for audio playback, and so we support every audio type Below is only small portion of supported file types. \begin{description} - \item mp3 (MPEG-1 Part 3 Layer 3) popular audio file format and \textit{de facto} standard for storing audio. Used by the Morrowind game. + \item mp3 ({MPEG}-1 {Part 3 Layer 3}) popular audio file format and \textit{de facto} standard for storing audio. Used by the \MW{} game. \item ogg open source, multimedia container file using high quality vorbis audio codec. Recommended. \end{description} @@ -103,17 +103,18 @@ only the most significant. \begin{description} \item bik videos used by original \MW{} game. - \item mp4 multimedia container which use more advanced codecs (MPEG-4 Parts 2,3,10) with a better audio and video compression rate, - but also requiring more {CPU} intensive decoding -- this makes it probably less suited for video games. + \item mp4 multimedia container which use more advanced codecs ({MPEG-4 Parts 2,3,10}) with a better audio and video compression rate, + but also requiring more {CPU} intensive decoding -- this makes it probably less suited for storing sounds in computer games, but good for videos. \item webm is a new, shiny and open source video format with excellent compression. It needs quite a lot of processing power to be decoded, but since game logic is not running during cut scenes we can recommended it for use with \OMW. \item ogv alternative, open source container using theora codec for video and vorbis for audio. \end{description} \subparagraph{Textures and images} -Original \MW{} game uses DDS and TGA files for all kind of two dimensional images and textures alike. In addition, engine supported BMP -files for some reason (BMP is a terrible format for a video game). We also support extended set of image files -- including JPEG and PNG. +Original \MW{} game uses {DDS} and {TGA} files for all kind of two dimensional images and textures alike. In addition, engine supported BMP +files for some reason ({BMP} is a terrible format for a video game). We also support extended set of image files -- including {JPEG} and {PNG}. JPEG and PNG files can be useful in some cases, for instance JPEG file is a valid option for skybox texture and PNG can useful for masks. -However please, keep in mind that JPEG can grow into large sizes quickly and are not the best option with DirectX rendering backend. +However please, keep in mind that JPEG can grow into large sizes quickly and are not the best option with {DirectX} rendering backend. You probabbly still want +to use {DDS} files for textures. %\subparagraph{Meshes} %TODO once we will support something more than just nifs \ No newline at end of file From 4ef2724f35abb5ebdbb902df943bc3284f4eb65f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 1 Dec 2013 13:24:28 +0100 Subject: [PATCH 39/56] Starting dialog window finished. --- manual/opencs/creating_file.tex | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/manual/opencs/creating_file.tex b/manual/opencs/creating_file.tex index 8cab726174..34780a03ed 100644 --- a/manual/opencs/creating_file.tex +++ b/manual/opencs/creating_file.tex @@ -10,8 +10,14 @@ to you with no surprise.\\ First, there is a \textbf{Create A New Game} button. Clearly, you should press it when you want to create a game file. Than, what \textbf{Create A New Addon} button do? Yes! You are right! This button will create any addon content file (and new project file associated with it)! Wonderful! And what the last remaining button do? \textbf{Edit A Content File}? Well, it comes with no surprise that this should be used when you need to alter existing content file, either a game or addon.\\ -\paragraph{Selecting Files} -As We wrote earlier, +\paragraph{Selecting Files For New Addon} +As We wrote earlier, both \OMW{} and \OCS{} are operating with dependency idea in mind. As You remember you should only depend on files you are actually using. But how?\\ +It is simple. When you click either \textbf{Create new Addon} you will be asked to choose those with a new dialog window. The window is using vertical layout, first you should consider the the top element, the one that allows you to select a game file with drop down menu. Since we are operating on the assumption that there is only one game file loaded at the time, you can depend only on one game file. Next, choose addons that you want to use in your addon with checkboxes.\\ + +The last thing to do is to name your your addon and click create. + +\paragraph{Selecting File for Editing} +Clicking \textbf{Edit A Content File} will show somewhat similar window. Here you should select your Game file with drop down menu. If you want to edit this game file, simply click \textbf{OK} button. If you want to alter addon depending on that file, mark it with checkbox and than click \textbf{Ok} button. \subsection{Advanced} If you are paying attention, you noticed any extra icon with wrench. This one will open small settings window. Options here are few, and easy to list. @@ -20,6 +26,4 @@ If you are paying attention, you noticed any extra icon with wrench. This one wi \item {Display format} can be used to configure behavior of the \OCS{} itself, however only in the limited degree. You can decide if you want \OCS{} to display icon, text or both in some columns of tables. \end{description} -%TODO configuration - And that would be it. There is no point spending more time here. We should go forward now. \ No newline at end of file From 890aca720e1fc0796340547948097518b59ddee6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 3 Dec 2013 15:35:03 +0100 Subject: [PATCH 40/56] correcting qoutes style and removing informations about settings from creating_file.tex. Thanks zini. --- manual/opencs/creating_file.tex | 6 +----- manual/opencs/filters.tex | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/manual/opencs/creating_file.tex b/manual/opencs/creating_file.tex index 34780a03ed..2c1377ec1e 100644 --- a/manual/opencs/creating_file.tex +++ b/manual/opencs/creating_file.tex @@ -20,10 +20,6 @@ The last thing to do is to name your your addon and click create. Clicking \textbf{Edit A Content File} will show somewhat similar window. Here you should select your Game file with drop down menu. If you want to edit this game file, simply click \textbf{OK} button. If you want to alter addon depending on that file, mark it with checkbox and than click \textbf{Ok} button. \subsection{Advanced} -If you are paying attention, you noticed any extra icon with wrench. This one will open small settings window. Options here are few, and easy to list. -\begin{description} - \item {Window Size} is needed to configure initial window size of the starting window. - \item {Display format} can be used to configure behavior of the \OCS{} itself, however only in the limited degree. You can decide if you want \OCS{} to display icon, text or both in some columns of tables. -\end{description} +If you are paying attention, you noticed any extra icon with wrench. This one will open small settings window. Those are general OpenCS settings. We will cover this is separate section.\\ And that would be it. There is no point spending more time here. We should go forward now. \ No newline at end of file diff --git a/manual/opencs/filters.tex b/manual/opencs/filters.tex index a5f88aebba..36d97e0f5e 100644 --- a/manual/opencs/filters.tex +++ b/manual/opencs/filters.tex @@ -102,7 +102,7 @@ you want to see, while the second one sets desired value inside of the cell. To String in programmers language is often\footnote{Often, not always. There are different programming languages using slightly different terms.} just a word for anything composed of characters. In case of \OCS{} this is in fact true for every value inside the column that is not composed of the pure numbers. Even columns containing only ``true`` and ``false`` values can be targeted by the string expression\footnote{There is no -Boolean (''true'' or ``false'') value in the \OCS. You should use string for those.}. String evaluates to true, +Boolean (``true'' or ``false'') value in the \OCS. You should use string for those.}. String evaluates to true, when record contains in the specified column exactly the same value as specified. Since majority of the columns contain string values, string is among the most often used expressions. Examples: @@ -157,7 +157,7 @@ As you would imagine the range can be specified as including a border value, or The same expression will evaluate to false for value equal 10. \end{itemize} -\paragraph{''true`` and ''false``} +\paragraph{``true'' and ``false''} Nullary \textit{true} and \textit{false} do not accept any arguments, and always evaluates to true (in case of \textit{true}) and false (in case of \textit{false}) no matter what. The main usage of this expressions is the give users ability to quickly disable some part of the filter that makes heavy use of the logical expressions. @@ -184,10 +184,10 @@ This is probably not the most useful filter on earth, but this is not a surprise \mono{or(string(``record type'', npc), string(``record type'', creature))} and will show both npcs and creatures. \paragraph{and -- and(expression1(), expression2())} -\textit{And} is a expression that will return true if all arguments evaluates to true. As in the case of ''or`` you can use two or more arguments, +\textit{And} is a expression that will return true if all arguments evaluates to true. As in the case of ``or'' you can use two or more arguments, separated by a comma. As we mentioned earlier in the \textit{not} filter, combining \textit{not} with \textit{and} can be very useful. For instance to show all armor types, -excluding gauntlets you can write the following: \mono{and (not string("armor type", ".* gauntlet"), string(''Record Type``, ''Armor``))}. +excluding gauntlets you can write the following: \mono{and (not string(``armor type'', ``.* gauntlet''), string(``Record Type'', ``Armor''))}. \subsubsection{Creating and saving filter} In order to create and save new filter, you should go to the filters table, right click and select option ``add record'' from the context menu. From fc8bd1aacb9ae79f89fe37a7a1c7e409b7d6f3e5 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 9 Dec 2013 21:13:06 +0100 Subject: [PATCH 41/56] Allow fatigue stat to become negative when fatigue damages are taken --- apps/openmw/mwclass/creature.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwmechanics/stat.hpp | 22 +++++++++++++++++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 9834807821..2e7f00dd33 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -199,7 +199,7 @@ namespace MWClass else { MWMechanics::DynamicStat fatigue(getCreatureStats(ptr).getFatigue()); - fatigue.setCurrent(fatigue.getCurrent() - damage); + fatigue.setCurrent(fatigue.getCurrent() - damage, true); getCreatureStats(ptr).setFatigue(fatigue); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e7c10d3c81..5f9b2de478 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -669,7 +669,7 @@ namespace MWClass else { MWMechanics::DynamicStat fatigue(getCreatureStats(ptr).getFatigue()); - fatigue.setCurrent(fatigue.getCurrent() - damage); + fatigue.setCurrent(fatigue.getCurrent() - damage, true); getCreatureStats(ptr).setFatigue(fatigue); } } diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 65d47c9c08..cb6c09014b 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -162,14 +162,26 @@ namespace MWMechanics setCurrent (getCurrent()+diff); } - void setCurrent (const T& value) + void setCurrent (const T& value, bool allowDecreaseBelowZero = false) { - mCurrent = value; + if (value > mCurrent) + { + // increase + mCurrent = value; - if (mCurrent<0) + if (mCurrent > getModified()) + mCurrent = getModified(); + } + else if (value > 0 || allowDecreaseBelowZero) + { + // allowed decrease + mCurrent = value; + } + else if (mCurrent > 0) + { + // capped decrease mCurrent = 0; - else if (mCurrent>getModified()) - mCurrent = getModified(); + } } void setModifier (const T& modifier) From 357ecd92b2c387dd7f7f93c91b0ff185df947cb3 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 10 Dec 2013 00:41:36 +0100 Subject: [PATCH 42/56] Do not display negative stat values Display zero instead of negative values. Also remove useless for loops and some unused attributes. --- apps/openmw/mwgui/hud.cpp | 56 ++++++++++++-------------- apps/openmw/mwgui/statswindow.cpp | 50 +++++++++-------------- apps/openmw/mwgui/windowmanagerimp.cpp | 27 ------------- apps/openmw/mwgui/windowmanagerimp.hpp | 2 - 4 files changed, 45 insertions(+), 90 deletions(-) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index f0843834d5..a78b1a6d1b 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -174,38 +174,32 @@ namespace MWGui void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { - static const char *ids[] = - { - "HBar", "MBar", "FBar", 0 - }; + int current = std::max(0, static_cast(value.getCurrent())); + int modified = static_cast(value.getModified()); - for (int i=0; ids[i]; ++i) - if (ids[i]==id) - { - MyGUI::Widget* w; - std::string valStr = boost::lexical_cast(value.getCurrent()) + "/" + boost::lexical_cast(value.getModified()); - switch (i) - { - case 0: - mHealth->setProgressRange (value.getModified()); - mHealth->setProgressPosition (value.getCurrent()); - getWidget(w, "HealthFrame"); - w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); - break; - case 1: - mMagicka->setProgressRange (value.getModified()); - mMagicka->setProgressPosition (value.getCurrent()); - getWidget(w, "MagickaFrame"); - w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); - break; - case 2: - mStamina->setProgressRange (value.getModified()); - mStamina->setProgressPosition (value.getCurrent()); - getWidget(w, "FatigueFrame"); - w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); - break; - } - } + MyGUI::Widget* w; + std::string valStr = boost::lexical_cast(current) + "/" + boost::lexical_cast(modified); + if (id == "HBar") + { + mHealth->setProgressRange(modified); + mHealth->setProgressPosition(current); + getWidget(w, "HealthFrame"); + w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); + } + else if (id == "MBar") + { + mMagicka->setProgressRange (modified); + mMagicka->setProgressPosition (current); + getWidget(w, "MagickaFrame"); + w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); + } + else if (id == "FBar") + { + mStamina->setProgressRange (modified); + mStamina->setProgressPosition (current); + getWidget(w, "FatigueFrame"); + w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); + } } void HUD::setDrowningTimeLeft(float time) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 136328f57e..ab6096b7e6 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -134,38 +134,28 @@ namespace MWGui void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat& value) { - static const char *ids[] = - { - "HBar", "MBar", "FBar", - 0 - }; + int current = std::max(0, static_cast(value.getCurrent())); + int modified = static_cast(value.getModified()); - for (int i=0; ids[i]; ++i) - { - if (ids[i]==id) - { - std::string id (ids[i]); - setBar (id, id + "T", static_cast(value.getCurrent()), static_cast(value.getModified())); + setBar (id, id + "T", current, modified); - // health, magicka, fatigue tooltip - MyGUI::Widget* w; - std::string valStr = boost::lexical_cast(int(value.getCurrent())) + "/" + boost::lexical_cast(int(value.getModified())); - if (i==0) - { - getWidget(w, "Health"); - w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); - } - else if (i==1) - { - getWidget(w, "Magicka"); - w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); - } - else if (i==2) - { - getWidget(w, "Fatigue"); - w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); - } - } + // health, magicka, fatigue tooltip + MyGUI::Widget* w; + std::string valStr = boost::lexical_cast(current) + "/" + boost::lexical_cast(modified); + if (id == "HBar") + { + getWidget(w, "Health"); + w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); + } + else if (id == "MBar") + { + getWidget(w, "Magicka"); + w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); + } + else if (id == "FBar") + { + getWidget(w, "Fatigue"); + w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 78986a0522..afa020082b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -112,9 +112,6 @@ namespace MWGui , mPlayerMinorSkills() , mPlayerMajorSkills() , mPlayerSkillValues() - , mPlayerHealth() - , mPlayerMagicka() - , mPlayerFatigue() , mGui(NULL) , mGuiModes() , mCursorManager(NULL) @@ -590,32 +587,8 @@ namespace MWGui mStatsWindow->setValue (id, value); mHud->setValue (id, value); mCharGen->setValue(id, value); - if (id == "HBar") - { - mPlayerHealth = value; - } - else if (id == "MBar") - { - mPlayerMagicka = value; - } - else if (id == "FBar") - { - mPlayerFatigue = value; - } } - #if 0 - MWMechanics::DynamicStat WindowManager::getValue(const std::string& id) - { - if(id == "HBar") - return mPlayerHealth; - else if (id == "MBar") - return mPlayerMagicka; - else if (id == "FBar") - return mPlayerFatigue; - } - #endif - void WindowManager::setValue (const std::string& id, const std::string& value) { mStatsWindow->setValue (id, value); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 4f19602958..743160aa82 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -346,8 +346,6 @@ namespace MWGui std::map > mPlayerAttributes; SkillList mPlayerMajorSkills, mPlayerMinorSkills; std::map > mPlayerSkillValues; - MWMechanics::DynamicStat mPlayerHealth, mPlayerMagicka, mPlayerFatigue; - MyGUI::Gui *mGui; // Gui std::vector mGuiModes; From 0c3c3ed8e95107745814f8fcfaa7b618544750ce Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 11 Dec 2013 15:15:30 +0100 Subject: [PATCH 43/56] Fix wind gravity affector --- components/nifogre/ogrenifloader.cpp | 2 +- components/nifogre/particles.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index e6c535b9b8..acf8ac13af 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -724,7 +724,7 @@ class NIFObjectLoader { const Nif::NiMaterialColorController *matCtrl = dynamic_cast(ctrls.getPtr()); Ogre::ControllerValueRealPtr dstval(OGRE_NEW MaterialColorController::Value(movable, matCtrl->data.getPtr(), &scene->mMaterialControllerMgr)); - AlphaController::Function* function = OGRE_NEW AlphaController::Function(matCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); + MaterialColorController::Function* function = OGRE_NEW MaterialColorController::Function(matCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); diff --git a/components/nifogre/particles.cpp b/components/nifogre/particles.cpp index 006a570dce..7b51f06679 100644 --- a/components/nifogre/particles.cpp +++ b/components/nifogre/particles.cpp @@ -763,7 +763,7 @@ public: protected: void applyWindForce(Ogre::ParticleSystem *psys, Ogre::Real timeElapsed) { - const Ogre::Vector3 vec = mDirection * mForce * timeElapsed; + const Ogre::Vector3 vec = mBone->_getDerivedOrientation() * mDirection * mForce * timeElapsed; Ogre::ParticleIterator pi = psys->_getIterator(); while (!pi.end()) { From 39eea24dc3866760cc40b79b6d57ebbc6799fc73 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Dec 2013 03:50:01 +0100 Subject: [PATCH 44/56] Don't try to show exceptions in a message box if SDL was not initialized --- apps/openmw/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index b1bbb14f23..13e9d9241f 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -3,8 +3,7 @@ #include -#include -#include +#include #include "engine.hpp" #if defined(_WIN32) && !defined(_CONSOLE) @@ -282,7 +281,7 @@ int main(int argc, char**argv) } catch (std::exception &e) { - if (isatty(fileno(stdin))) + if (isatty(fileno(stdin)) || !SDL_WasInit(SDL_INIT_VIDEO)) std::cerr << "\nERROR: " << e.what() << std::endl; else SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL); From 530d06ab54352c79bca6c168f270168e8bcaa29b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 14 Dec 2013 05:07:08 +0100 Subject: [PATCH 45/56] Remove unused code --- components/CMakeLists.txt | 4 +- components/files/filelibrary.cpp | 120 ------------------------------- components/files/filelibrary.hpp | 49 ------------- components/files/fileops.cpp | 120 ------------------------------- components/files/fileops.hpp | 38 ---------- 5 files changed, 2 insertions(+), 329 deletions(-) delete mode 100644 components/files/filelibrary.cpp delete mode 100644 components/files/filelibrary.hpp delete mode 100644 components/files/fileops.cpp delete mode 100644 components/files/fileops.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 50ac236c8a..a037fd5fa4 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -47,8 +47,8 @@ add_component_dir (misc ) add_component_dir (files - linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager - filelibrary constrainedfiledatastream lowlevelfile + linuxpath windowspath macospath fixedpath multidircollection collections configurationmanager + constrainedfiledatastream lowlevelfile ) add_component_dir (compiler diff --git a/components/files/filelibrary.cpp b/components/files/filelibrary.cpp deleted file mode 100644 index ce2d95f57c..0000000000 --- a/components/files/filelibrary.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "filelibrary.hpp" - -#include - -#include -#include <../components/misc/stringops.hpp> - -namespace Files -{ - // Looks for a string in a vector of strings - bool containsVectorString(const StringVector& list, const std::string& str) - { - for (StringVector::const_iterator iter = list.begin(); - iter != list.end(); ++iter) - { - if (*iter == str) - return true; - } - return false; - } - - // Searches a path and adds the results to the library - void FileLibrary::add(const boost::filesystem::path &root, bool recursive, bool strict, - const StringVector &acceptableExtensions) - { - if (!boost::filesystem::exists(root)) - { - std::cout << "Warning " << root.string() << " does not exist.\n"; - return; - } - - std::string fileExtension; - std::string type; - - // remember the last location of the priority list when listing new items - int length = mPriorityList.size(); - - // First makes a list of all candidate files - FileLister(root, mPriorityList, recursive); - - // Then sort these files into sections according to the folder they belong to - for (PathContainer::iterator listIter = mPriorityList.begin() + length; - listIter != mPriorityList.end(); ++listIter) - { - if( !acceptableExtensions.empty() ) - { - fileExtension = boost::filesystem::path (listIter->extension()).string(); - Misc::StringUtils::toLower(fileExtension); - if(!containsVectorString(acceptableExtensions, fileExtension)) - continue; - } - - type = boost::filesystem::path (listIter->parent_path().leaf()).string(); - if (!strict) - Misc::StringUtils::toLower(type); - - mMap[type].push_back(*listIter); - // std::cout << "Added path: " << listIter->string() << " in section "<< type <second); - } - } - - // Searches the library for an item and returns a boost path to it - boost::filesystem::path FileLibrary::locate(std::string item, bool strict, bool ignoreExtensions, std::string sectionName) - { - boost::filesystem::path result(""); - if (sectionName == "") - { - return FileListLocator(mPriorityList, boost::filesystem::path(item), strict, ignoreExtensions); - } - else - { - if (!containsSection(sectionName, strict)) - { - std::cout << "Warning: There is no section named " << sectionName << "\n"; - return result; - } - result = FileListLocator(mMap[sectionName], boost::filesystem::path(item), strict, ignoreExtensions); - } - return result; - } - - // Prints all the available sections, used for debugging - void FileLibrary::printSections() - { - for(StringPathContMap::const_iterator mapIter = mMap.begin(); - mapIter != mMap.end(); ++mapIter) - { - std::cout << mapIter->first < - -namespace Files -{ - typedef std::map StringPathContMap; - typedef std::vector StringVector; - - /// Looks for a string in a vector of strings - bool containsVectorString(const StringVector& list, const std::string& str); - - /// \brief Searches directories and makes lists of files according to folder name - class FileLibrary - { - private: - StringPathContMap mMap; - PathContainer mEmptyPath; - PathContainer mPriorityList; - - public: - /// Searches a path and adds the results to the library - /// Recursive search and fs strict options are available - /// Takes a vector of acceptable files extensions, if none is given it lists everything. - void add(const boost::filesystem::path &root, bool recursive, bool strict, - const StringVector &acceptableExtensions); - - /// Returns true if the named section exists - /// You can run this check before running section() - bool containsSection(std::string sectionName, bool strict); - - /// Returns a pointer to const for a section of the library - /// which is essentially a PathContainer. - /// If the section does not exists it returns a pointer to an empty path. - const PathContainer* section(std::string sectionName, bool strict); - - /// Searches the library for an item and returns a boost path to it - /// Optionally you can provide a specific section - /// The result is the first that comes up according to alphabetical - /// section naming - boost::filesystem::path locate(std::string item, bool strict, bool ignoreExtensions, std::string sectionName=""); - - /// Prints all the available sections, used for debugging - void printSections(); - }; -} - -#endif diff --git a/components/files/fileops.cpp b/components/files/fileops.cpp deleted file mode 100644 index fbc2eef056..0000000000 --- a/components/files/fileops.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "fileops.hpp" - -#include - -#include -#include -#include <../components/misc/stringops.hpp> - -namespace Files -{ - -bool isFile(const char *name) -{ - return boost::filesystem::exists(boost::filesystem::path(name)); -} - - // Returns true if the last part of the superset matches the subset - bool endingMatches(const std::string& superset, const std::string& subset) - { - if (subset.length() > superset.length()) - return false; - return superset.substr(superset.length() - subset.length()) == subset; - } - - // Makes a list of files from a directory - void FileLister( boost::filesystem::path currentPath, Files::PathContainer& list, bool recursive) - { - if (!boost::filesystem::exists(currentPath)) - { - std::cout << "WARNING: " << currentPath.string() << " does not exist.\n"; - return ; - } - if (recursive) - { - for ( boost::filesystem::recursive_directory_iterator end, itr(currentPath.string()); - itr != end; ++itr ) - { - if ( boost::filesystem::is_regular_file(*itr)) - list.push_back(itr->path()); - } - } - else - { - for ( boost::filesystem::directory_iterator end, itr(currentPath.string()); - itr != end; ++itr ) - { - if ( boost::filesystem::is_regular_file(*itr)) - list.push_back(itr->path()); - } - } - } - - // Locates path in path container - boost::filesystem::path FileListLocator (const Files::PathContainer& list, const boost::filesystem::path& toFind, - bool strict, bool ignoreExtensions) - { - boost::filesystem::path result(""); - if (list.empty()) - return result; - - std::string toFindStr; - if (ignoreExtensions) - toFindStr = boost::filesystem::basename(toFind); - else - toFindStr = toFind.string(); - - std::string fullPath; - - // The filesystems slash sets the default slash - std::string slash; - std::string wrongslash; - if(list[0].string().find("\\") != std::string::npos) - { - slash = "\\"; - wrongslash = "/"; - } - else - { - slash = "/"; - wrongslash = "\\"; - } - - // The file being looked for is converted to the new slash - if(toFindStr.find(wrongslash) != std::string::npos ) - { - boost::replace_all(toFindStr, wrongslash, slash); - } - - if (!strict) - { - Misc::StringUtils::toLower(toFindStr); - } - - for (Files::PathContainer::const_iterator it = list.begin(); it != list.end(); ++it) - { - fullPath = it->string(); - if (ignoreExtensions) - fullPath.erase(fullPath.length() - - boost::filesystem::path (it->extension()).string().length()); - - if (!strict) - { - Misc::StringUtils::toLower(fullPath); - } - if(endingMatches(fullPath, toFindStr)) - { - result = *it; - break; - } - } - return result; - } - - // Overloaded form of the locator that takes a string and returns a string - std::string FileListLocator (const Files::PathContainer& list,const std::string& toFind, bool strict, bool ignoreExtensions) - { - return FileListLocator(list, boost::filesystem::path(toFind), strict, ignoreExtensions).string(); - } - -} diff --git a/components/files/fileops.hpp b/components/files/fileops.hpp deleted file mode 100644 index bf1c51485f..0000000000 --- a/components/files/fileops.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef COMPONENTS_FILES_FILEOPS_HPP -#define COMPONENTS_FILES_FILEOPS_HPP - -#include -#include -#include - -#include - -namespace Files -{ - -///\brief Check if a given path is an existing file (not a directory) -///\param [in] name - filename -bool isFile(const char *name); - - /// A vector of Boost Paths, very handy - typedef std::vector PathContainer; - - /// Makes a list of files from a directory by taking a boost - /// path and a Path Container and adds to the Path container - /// all files in the path. It has a recursive option. - void FileLister( boost::filesystem::path currentPath, Files::PathContainer& list, bool recursive); - - /// Locates boost path in path container - /// returns the path from the container - /// that contains the searched path. - /// If it's not found it returns and empty path - /// Takes care of slashes, backslashes and it has a strict option. - boost::filesystem::path FileListLocator (const Files::PathContainer& list, const boost::filesystem::path& toFind, - bool strict, bool ignoreExtensions); - - /// Overloaded form of the locator that takes a string and returns a string - std::string FileListLocator (const Files::PathContainer& list,const std::string& toFind, bool strict, bool ignoreExtensions); - -} - -#endif /* COMPONENTS_FILES_FILEOPS_HPP */ From 4bc4af6bf0116ef1df832cca56395ea6023d7905 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 14 Dec 2013 22:01:24 +0100 Subject: [PATCH 46/56] Enable microcode caching for Ogre 1.9+ --- extern/shiny/Platforms/Ogre/OgrePlatform.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/extern/shiny/Platforms/Ogre/OgrePlatform.cpp b/extern/shiny/Platforms/Ogre/OgrePlatform.cpp index 3725d5f354..9f309fbcda 100644 --- a/extern/shiny/Platforms/Ogre/OgrePlatform.cpp +++ b/extern/shiny/Platforms/Ogre/OgrePlatform.cpp @@ -64,8 +64,11 @@ namespace sh bool OgrePlatform::supportsShaderSerialization () { - // Not very reliable in OpenGL mode (requires extension), and somehow doesn't work on linux even if the extension is present + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + return true; + #else return Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") == std::string::npos; + #endif } bool OgrePlatform::supportsMaterialQueuedListener () @@ -110,10 +113,15 @@ namespace sh void OgrePlatform::serializeShaders (const std::string& file) { - std::fstream output; - output.open(file.c_str(), std::ios::out | std::ios::binary); - Ogre::DataStreamPtr shaderCache (OGRE_NEW Ogre::FileStreamDataStream(file, &output, false)); - Ogre::GpuProgramManager::getSingleton().saveMicrocodeCache(shaderCache); + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + if (Ogre::GpuProgramManager::getSingleton().isCacheDirty()) + #endif + { + std::fstream output; + output.open(file.c_str(), std::ios::out | std::ios::binary); + Ogre::DataStreamPtr shaderCache (OGRE_NEW Ogre::FileStreamDataStream(file, &output, false)); + Ogre::GpuProgramManager::getSingleton().saveMicrocodeCache(shaderCache); + } } void OgrePlatform::deserializeShaders (const std::string& file) @@ -143,7 +151,7 @@ namespace sh else if (typeid(*value) == typeid(IntValue)) type = Ogre::GCT_INT1; else - assert(0); + throw std::runtime_error("unexpected type"); params->addConstantDefinition(name, type); mSharedParameters[name] = params; } From cd756a8a398d83034517cd1f5ae9d0ce0bb828fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 16 Dec 2013 13:22:27 +0100 Subject: [PATCH 47/56] Fix incorrect value for partially used items (missing float casts). Make sure the correct value is displayed in tooltips. --- apps/openmw/mwclass/apparatus.cpp | 2 +- apps/openmw/mwclass/armor.cpp | 4 ++-- apps/openmw/mwclass/book.cpp | 2 +- apps/openmw/mwclass/clothing.cpp | 2 +- apps/openmw/mwclass/ingredient.cpp | 2 +- apps/openmw/mwclass/light.cpp | 2 +- apps/openmw/mwclass/lockpick.cpp | 4 ++-- apps/openmw/mwclass/potion.cpp | 2 +- apps/openmw/mwclass/probe.cpp | 4 ++-- apps/openmw/mwclass/repair.cpp | 4 ++-- apps/openmw/mwclass/weapon.cpp | 4 ++-- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 697b755792..53c62273dc 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -124,7 +124,7 @@ namespace MWClass std::string text; text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index f3f36542a1..5b2b7caa39 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -172,7 +172,7 @@ namespace MWClass if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue; else - return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr)); + return ref->mBase->mData.mValue * (static_cast(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr)); } void Armor::registerSelf() @@ -248,7 +248,7 @@ namespace MWClass + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")"; - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index b22cbc31fc..1da9209706 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -136,7 +136,7 @@ namespace MWClass std::string text; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 8941f36275..c162bbe9de 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -191,7 +191,7 @@ namespace MWClass std::string text; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 06d9d5d235..4296d4e1b6 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -145,7 +145,7 @@ namespace MWClass std::string text; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index a031d25563..6a6133cb92 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -183,7 +183,7 @@ namespace MWClass std::string text; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 73b47d6af9..e1dc5b2e14 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -89,7 +89,7 @@ namespace MWClass if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue; else - return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr)); + return ref->mBase->mData.mValue * (static_cast(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr)); } void Lockpick::registerSelf() @@ -141,7 +141,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 883473eb33..e276c58aa5 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -128,7 +128,7 @@ namespace MWClass std::string text; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 845c2a0d00..b54464acdc 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -88,7 +88,7 @@ namespace MWClass if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue; else - return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr)); + return ref->mBase->mData.mValue * (static_cast(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr)); } void Probe::registerSelf() @@ -140,7 +140,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index dbfa9f0f62..ce2b4ff10c 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -79,7 +79,7 @@ namespace MWClass if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue; else - return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr)); + return ref->mBase->mData.mValue * (static_cast(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr)); } void Repair::registerSelf() @@ -144,7 +144,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index b1bf2b0b7f..a09e83380c 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -157,7 +157,7 @@ namespace MWClass if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue; else - return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr)); + return ref->mBase->mData.mValue * (static_cast(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr)); } void Weapon::registerSelf() @@ -346,7 +346,7 @@ namespace MWClass } text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); + text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); info.enchant = ref->mBase->mEnchant; From 56893a097def1184301af4c635a119856f25850e Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 16 Dec 2013 13:31:03 +0100 Subject: [PATCH 48/56] Don't stack used torches --- apps/openmw/mwworld/class.cpp | 2 +- apps/openmw/mwworld/class.hpp | 2 +- apps/openmw/mwworld/containerstore.cpp | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index d3d1aff49b..ffe81a4ac8 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -139,7 +139,7 @@ namespace MWWorld float Class::getRemainingUsageTime (const Ptr& ptr) const { - throw std::runtime_error ("class does not support time-based uses"); + return -1; } std::string Class::getScript (const Ptr& ptr) const diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 2db293e688..cb6690a464 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -162,7 +162,7 @@ namespace MWWorld virtual float getRemainingUsageTime (const Ptr& ptr) const; ///< Returns the remaining duration of the object, such as an equippable light - /// source. (default implementation: throw an exception) + /// source. (default implementation: -1, i.e. infinite) virtual std::string getScript (const Ptr& ptr) const; ///< Return name of the script attached to ptr (default implementation: return an empty diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index d1d16ee01d..3797e69223 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -109,6 +109,8 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) && ptr1.getCellRef().mOwner == ptr2.getCellRef().mOwner && ptr1.getCellRef().mSoul == ptr2.getCellRef().mSoul + && ptr1.getClass().getRemainingUsageTime(ptr1) == ptr2.getClass().getRemainingUsageTime(ptr2) + && cls1.getScript(ptr1) == cls2.getScript(ptr2) // item that is already partly used up never stacks From eb5e4ecec2f15dcc6ec22b12159d49b686c59427 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 16 Dec 2013 15:35:06 +0100 Subject: [PATCH 49/56] Remove more unused code --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 1 - apps/openmw/mwgui/loadingscreen.cpp | 36 +------- apps/openmw/mwrender/compositors.cpp | 108 ---------------------- apps/openmw/mwrender/compositors.hpp | 64 ------------- apps/openmw/mwrender/renderingmanager.cpp | 42 +-------- apps/openmw/mwrender/renderingmanager.hpp | 6 -- apps/openmw/mwrender/water.hpp | 2 - 8 files changed, 7 insertions(+), 254 deletions(-) delete mode 100644 apps/openmw/mwrender/compositors.cpp delete mode 100644 apps/openmw/mwrender/compositors.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 90fdd11ba9..5a062575c7 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -19,7 +19,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation actors objects renderinginterface localmap occlusionquery water shadows - compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction + characterpreview externalrendering globalmap videoplayer ripplesimulation refraction terrainstorage ) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8141af7124..961d3d9587 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -80,7 +80,6 @@ namespace MWBase Render_CollisionDebug, Render_Wireframe, Render_Pathgrid, - Render_Compositors, Render_BoundingBoxes }; diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 4bd383c2f3..868b582096 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -1,8 +1,6 @@ #include "loadingscreen.hpp" #include -#include -#include #include @@ -199,28 +197,7 @@ namespace MWGui MWBase::Environment::get().getInputManager()->update(0, true); - Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0)); - - bool hasCompositor = chain->getCompositor ("gbufferFinalizer"); - - - if (!hasCompositor) - { - mWindow->getViewport(0)->setClearEveryFrame(false); - } - else - { - if (!mFirstLoad) - { - mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName()); - mRectangle->setVisible(true); - } - - for (unsigned int i = 0; igetNumCompositors(); ++i) - { - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), false); - } - } + mWindow->getViewport(0)->setClearEveryFrame(false); // First, swap buffers from last draw, then, queue an update of the // window contents, but don't swap buffers (which would have @@ -231,15 +208,8 @@ namespace MWGui mWindow->update(false); - if (!hasCompositor) - mWindow->getViewport(0)->setClearEveryFrame(true); - else - { - for (unsigned int i = 0; igetNumCompositors(); ++i) - { - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), true); - } - } + mWindow->getViewport(0)->setClearEveryFrame(true); + mRectangle->setVisible(false); diff --git a/apps/openmw/mwrender/compositors.cpp b/apps/openmw/mwrender/compositors.cpp deleted file mode 100644 index b1c98a3067..0000000000 --- a/apps/openmw/mwrender/compositors.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "compositors.hpp" - -#include -#include -#include -#include - -using namespace MWRender; - -Compositors::Compositors(Ogre::Viewport* vp) : - mViewport(vp) - , mEnabled(true) -{ -} - -Compositors::~Compositors() -{ - Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); -} - -void Compositors::setEnabled (const bool enabled) -{ - for (CompositorMap::iterator it=mCompositors.begin(); - it != mCompositors.end(); ++it) - { - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, it->first, enabled && it->second.first); - } - mEnabled = enabled; -} - -void Compositors::recreate() -{ - Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); - - CompositorMap temp = mCompositors; - mCompositors.clear(); - - for (CompositorMap::iterator it=temp.begin(); - it != temp.end(); ++it) - { - addCompositor(it->first, it->second.second); - setCompositorEnabled(it->first, mEnabled && it->second.first); - } -} - -void Compositors::addCompositor (const std::string& name, const int priority) -{ - int id = 0; - - for (CompositorMap::iterator it=mCompositors.begin(); - it != mCompositors.end(); ++it) - { - if (it->second.second > priority) - break; - ++id; - } - Ogre::CompositorManager::getSingleton().addCompositor (mViewport, name, id); - - mCompositors[name] = std::make_pair(false, priority); -} - -void Compositors::setCompositorEnabled (const std::string& name, const bool enabled) -{ - mCompositors[name].first = enabled; - Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled); -} - -void Compositors::removeAll() -{ - Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); - - mCompositors.clear(); -} - -bool Compositors::anyCompositorEnabled() -{ - for (CompositorMap::iterator it=mCompositors.begin(); - it != mCompositors.end(); ++it) - { - if (it->second.first && mEnabled) - return true; - } - return false; -} - -void Compositors::countTrianglesBatches(unsigned int &triangles, unsigned int &batches) -{ - triangles = 0; - batches = 0; - - Ogre::CompositorInstance* c = NULL; - Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain (mViewport); - // accumulate tris & batches from all compositors with all their render targets - for (unsigned int i=0; i < chain->getNumCompositors(); ++i) - { - if (chain->getCompositor(i)->getEnabled()) - { - c = chain->getCompositor(i); - for (unsigned int j = 0; j < c->getTechnique()->getNumTargetPasses(); ++j) - { - std::string textureName = c->getTechnique()->getTargetPass(j)->getOutputName(); - Ogre::RenderTarget* rt = c->getRenderTarget(textureName); - triangles += rt->getTriangleCount(); - batches += rt->getBatchCount(); - } - } - } -} diff --git a/apps/openmw/mwrender/compositors.hpp b/apps/openmw/mwrender/compositors.hpp deleted file mode 100644 index e5dd7503ce..0000000000 --- a/apps/openmw/mwrender/compositors.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef GAME_MWRENDER_COMPOSITORS_H -#define GAME_MWRENDER_COMPOSITORS_H - -#include -#include - -namespace Ogre -{ - class Viewport; -} - -namespace MWRender -{ - typedef std::map < std::string, std::pair > CompositorMap; - - /// \brief Manages a set of compositors for one viewport - class Compositors - { - public: - Compositors(Ogre::Viewport* vp); - virtual ~Compositors(); - - /** - * enable or disable all compositors globally - */ - void setEnabled (const bool enabled); - - void setViewport(Ogre::Viewport* vp) { mViewport = vp; } - - /// recreate compositors (call this after viewport size changes) - void recreate(); - - bool toggle() { setEnabled(!mEnabled); return mEnabled; } - - /** - * enable or disable a specific compositor - * @note enable has no effect if all compositors are globally disabled - */ - void setCompositorEnabled (const std::string& name, const bool enabled); - - /** - * @param name of compositor - * @param priority, lower number will be first in the chain - */ - void addCompositor (const std::string& name, const int priority); - - bool anyCompositorEnabled(); - - void countTrianglesBatches(unsigned int &triangles, unsigned int &batches); - - void removeAll (); - - protected: - /// maps compositor name to its "enabled" state - CompositorMap mCompositors; - - bool mEnabled; - - Ogre::Viewport* mViewport; - }; - -} - -#endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index b216c789f7..0b10791b8b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -8,10 +8,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -43,7 +39,6 @@ #include "shadows.hpp" #include "localmap.hpp" #include "water.hpp" -#include "compositors.hpp" #include "npcanimation.hpp" #include "externalrendering.hpp" #include "globalmap.hpp" @@ -87,8 +82,6 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b mRendering.getWindow()->addListener(this); mRendering.setWindowListener(this); - mCompositors = new Compositors(mRendering.getViewport()); - mWater = 0; // material system @@ -157,8 +150,6 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false"); sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty (new sh::Vector4(0,0,0,0))); - applyCompositors(); - mRootNode = mRendering.getScene()->getRootSceneNode(); mRootNode->createChildSceneNode("player"); @@ -198,7 +189,6 @@ RenderingManager::~RenderingManager () delete mTerrain; delete mLocalMap; delete mOcclusionQuery; - delete mCompositors; delete mWater; delete mVideoPlayer; delete mActors; @@ -478,29 +468,21 @@ bool RenderingManager::toggleRenderMode(int mode) { if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) { - mCompositors->setEnabled(false); - mRendering.getCamera()->setPolygonMode(PM_WIREFRAME); return true; } else { - mCompositors->setEnabled(true); - mRendering.getCamera()->setPolygonMode(PM_SOLID); return false; } } - else if (mode == MWBase::World::Render_BoundingBoxes) + else //if (mode == MWBase::World::Render_BoundingBoxes) { bool show = !mRendering.getScene()->getShowBoundingBoxes(); mRendering.getScene()->showBoundingBoxes(show); return show; } - else //if (mode == MWBase::World::Render_Compositors) - { - return mCompositors->toggle(); - } } void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell) @@ -745,11 +727,6 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds) return Vector4(min_x, min_y, max_x, max_y); } -Compositors* RenderingManager::getCompositors() -{ - return mCompositors; -} - void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { bool changeRes = false; @@ -795,7 +772,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec } else if (it->second == "shader" && it->first == "Water") { - applyCompositors(); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); rebuild = true; mRendering.getViewport ()->setClearEveryFrame (true); @@ -883,28 +859,16 @@ void RenderingManager::windowResized(int x, int y) Settings::Manager::setInt("resolution x", "Video", x); Settings::Manager::setInt("resolution y", "Video", y); mRendering.adjustViewport(); - mCompositors->recreate(); mVideoPlayer->setResolution (x, y); MWBase::Environment::get().getWindowManager()->windowResized(x,y); } -void RenderingManager::applyCompositors() -{ -} - void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) { - if (mCompositors->anyCompositorEnabled()) - { - mCompositors->countTrianglesBatches(triangles, batches); - } - else - { - triangles = mRendering.getWindow()->getTriangleCount(); - batches = mRendering.getWindow()->getBatchCount(); - } + batches = mRendering.getWindow()->getBatchCount(); + triangles = mRendering.getWindow()->getTriangleCount(); } void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e5dcf0aebc..abc8fd71a7 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -48,7 +48,6 @@ namespace MWRender class Shadows; class LocalMap; class Water; - class Compositors; class ExternalRendering; class GlobalMap; class VideoPlayer; @@ -96,7 +95,6 @@ public: void renderPlayer(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); - Compositors* getCompositors(); void toggleLight(); bool toggleRenderMode(int mode); @@ -224,8 +222,6 @@ private: void setMenuTransparency(float val); - void applyCompositors(); - bool mSunEnabled; MWWorld::Fallback* mFallback; @@ -269,8 +265,6 @@ private: MWRender::Shadows* mShadows; - MWRender::Compositors* mCompositors; - VideoPlayer* mVideoPlayer; }; diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index bc15b4980a..481a412977 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -133,8 +133,6 @@ namespace MWRender { RenderingManager* mRendering; SkyManager* mSky; - std::string mCompositorName; - Ogre::MaterialPtr mMaterial; bool mUnderwaterEffect; From da9b67b6d22b1e34ae7f3895f424a75fae04bd34 Mon Sep 17 00:00:00 2001 From: pvdk Date: Mon, 16 Dec 2013 20:40:58 +0100 Subject: [PATCH 50/56] Fix for Bug #922: Launcher writing merged openmw.cfg files --- apps/launcher/maindialog.cpp | 26 ++++++++++++++++ apps/launcher/settings/gamesettings.cpp | 41 ++++++++++++++++--------- apps/launcher/settings/gamesettings.hpp | 11 +++++++ 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 4012a1fbd5..a6ac3d78d7 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -443,6 +443,32 @@ bool Launcher::MainDialog::setupGameSettings() QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string()); + // Load the user config file first, separately + // So we can write it properly, uncontaminated + QString path = userPath + QLatin1String("openmw.cfg"); + QFile file(path); + + qDebug() << "Loading config file:" << qPrintable(path); + + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error opening OpenMW configuration file")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(QObject::tr("
Could not open %0 for reading

\ + Please make sure you have the right permissions \ + and try again.
").arg(file.fileName())); + msgBox.exec(); + return false; + } + QTextStream stream(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); + + mGameSettings.readUserFile(stream); + } + + // Now the rest QStringList paths; paths.append(userPath + QString("openmw.cfg")); paths.append(QString("openmw.cfg")); diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 41113c35aa..e7e5cf1ea7 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -90,6 +90,16 @@ QStringList Launcher::GameSettings::values(const QString &key, const QStringList } bool Launcher::GameSettings::readFile(QTextStream &stream) +{ + return readFile(stream, mSettings); +} + +bool Launcher::GameSettings::readUserFile(QTextStream &stream) +{ + return readFile(stream, mUserSettings); +} + +bool Launcher::GameSettings::readFile(QTextStream &stream, QMap &settings) { QMap cache; QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); @@ -107,10 +117,10 @@ bool Launcher::GameSettings::readFile(QTextStream &stream) // Don't remove existing data entries if (key != QLatin1String("data")) - mSettings.remove(key); + settings.remove(key); QStringList values = cache.values(key); - values.append(mSettings.values(key)); + values.append(settings.values(key)); if (!values.contains(value)) { cache.insertMulti(key, value); @@ -118,23 +128,24 @@ bool Launcher::GameSettings::readFile(QTextStream &stream) } } - if (mSettings.isEmpty()) { - mSettings = cache; // This is the first time we read a file + if (settings.isEmpty()) { + settings = cache; // This is the first time we read a file validatePaths(); return true; } // Merge the changed keys with those which didn't - mSettings.unite(cache); + settings.unite(cache); validatePaths(); return true; } + bool Launcher::GameSettings::writeFile(QTextStream &stream) { // Iterate in reverse order to preserve insertion order - QMapIterator i(mSettings); + QMapIterator i(mUserSettings); i.toBack(); while (i.hasPrevious()) { @@ -162,7 +173,7 @@ bool Launcher::GameSettings::writeFile(QTextStream &stream) } - QStringList content = mSettings.values(QString("content")); + QStringList content = mUserSettings.values(QString("content")); for (int i = content.count(); i--;) { stream << "content=" << content.at(i) << "\n"; } @@ -172,14 +183,14 @@ bool Launcher::GameSettings::writeFile(QTextStream &stream) bool Launcher::GameSettings::hasMaster() { - bool result = false; - QStringList content = mSettings.values(QString("content")); - for (int i = 0; i < content.count(); ++i) { - if (content.at(i).contains(".omwgame") || content.at(i).contains(".esm")) { - result = true; - break; + bool result = false; + QStringList content = mSettings.values(QString("content")); + for (int i = 0; i < content.count(); ++i) { + if (content.at(i).contains(".omwgame") || content.at(i).contains(".esm")) { + result = true; + break; + } } - } - return result; + return result; } diff --git a/apps/launcher/settings/gamesettings.hpp b/apps/launcher/settings/gamesettings.hpp index 60236200a9..df82150742 100644 --- a/apps/launcher/settings/gamesettings.hpp +++ b/apps/launcher/settings/gamesettings.hpp @@ -31,6 +31,7 @@ namespace Launcher inline void setValue(const QString &key, const QString &value) { mSettings.insert(key, value); + mUserSettings.insert(key, value); } inline void setMultiValue(const QString &key, const QString &value) @@ -38,11 +39,16 @@ namespace Launcher QStringList values = mSettings.values(key); if (!values.contains(value)) mSettings.insertMulti(key, value); + + values = mUserSettings.values(key); + if (!values.contains(value)) + mUserSettings.insertMulti(key, value); } inline void remove(const QString &key) { mSettings.remove(key); + mUserSettings.remove(key); } inline QStringList getDataDirs() { return mDataDirs; } @@ -52,7 +58,11 @@ namespace Launcher bool hasMaster(); QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); + bool readFile(QTextStream &stream); + bool readFile(QTextStream &stream, QMap &settings); + bool readUserFile(QTextStream &stream); + bool writeFile(QTextStream &stream); private: @@ -60,6 +70,7 @@ namespace Launcher void validatePaths(); QMap mSettings; + QMap mUserSettings; QStringList mDataDirs; QString mDataLocal; From 876fb9a899cf19a045b0b9a63be6144f1f1c0daa Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 00:11:14 +0100 Subject: [PATCH 51/56] Addition to bb4bd999ba706e : adjust position for objects placed from inventory --- apps/openmw/mwworld/worldimp.cpp | 8 ++++---- apps/openmw/mwworld/worldimp.hpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f64d221223..448211bc2e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1095,7 +1095,7 @@ namespace MWWorld MWWorld::Ptr World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) { - return copyObjectToCell(ptr,Cell,pos); + return copyObjectToCell(ptr,Cell,pos,false); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const @@ -1516,7 +1516,7 @@ namespace MWWorld // copy the object and set its count int origCount = object.getRefData().getCount(); object.getRefData().setCount(amount); - Ptr dropped = copyObjectToCell(object, *cell, pos); + Ptr dropped = copyObjectToCell(object, *cell, pos, true); object.getRefData().setCount(origCount); // only the player place items in the world, so no need to check actor @@ -1537,13 +1537,13 @@ namespace MWWorld } - Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos) + Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos, bool adjustPos) { /// \todo add searching correct cell for position specified MWWorld::Ptr dropped = MWWorld::Class::get(object).copyToCell(object, cell, pos); - if (object.getClass().isActor()) + if (object.getClass().isActor() || adjustPos) { Ogre::Vector3 min, max; if (mPhysics->getObjectAABB(object, min, max)) { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index c8133441db..5a51cb773c 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -114,8 +114,7 @@ namespace MWWorld bool moveObjectImp (const Ptr& ptr, float x, float y, float z); ///< @return true if the active cell (cell player is in) changed - - Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); + Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos, bool adjustPos=true); void updateWindowManager (); void performUpdateSceneQueries (); From a0d38dfb6371d3eeb2da5aa1e82a781ec5d48022 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 00:26:08 +0100 Subject: [PATCH 52/56] Fix highlighted topics being selectable when in a choice --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 6 ++---- apps/openmw/mwgui/dialogue.cpp | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 52493bf765..3951cedcbc 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -413,10 +413,6 @@ namespace MWDialogue void DialogueManager::goodbyeSelected() { - // Do not close the dialogue window if the player has to answer a question - if (mIsInChoice) - return; - MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue); // Apply disposition change to NPC's base disposition @@ -474,6 +470,8 @@ namespace MWDialogue void DialogueManager::goodbye() { + mIsInChoice = true; + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->goodbye(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 71995f97fd..914302d84e 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -302,6 +302,8 @@ namespace MWGui void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) { + if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice()) + return; MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); } From 9afdf71af30c42e6162532fa1bb9ee20868b459a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 00:37:57 +0100 Subject: [PATCH 53/56] Fix crash with player->position command --- apps/openmw/mwworld/scene.cpp | 3 +-- apps/openmw/mwworld/scene.hpp | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 25ce038f36..dab272f7c0 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -203,6 +203,7 @@ namespace MWWorld void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) { + mRendering.enableTerrain(true); Nif::NIFFile::CacheLock cachelock; Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); @@ -436,8 +437,6 @@ namespace MWWorld MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y); - mRendering.enableTerrain(true); - changeCell (x, y, position, true); } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index e3edad352a..73c3c4b126 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -71,8 +71,6 @@ namespace MWWorld void loadCell (CellStore *cell, Loading::Listener* loadingListener); void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos); - ///< Move from exterior to interior or from interior cell to a different - /// interior cell. CellStore* getCurrentCell (); From 6a3eb3b355ecff7983ad61eeaad01fb576568e3f Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 01:31:12 +0100 Subject: [PATCH 54/56] Better way of reversing layer UV. --- files/materials/terrain.shader | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index eda80c9e30..7903292d30 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -335,7 +335,7 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5; float4 albedo = float4(0,0,0,1); - float2 layerUV = UV * 16; + float2 layerUV = float2(UV.x, 1.f-UV.y) * 16; // Reverse Y, required to get proper tangents float2 thisLayerUV; float4 normalTex; @@ -355,8 +355,6 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5; #endif thisLayerUV = layerUV; - // required to play nicely with the tangents - thisLayerUV.y *= -1; #if @shPropertyBool(use_parallax_@shIterator) thisLayerUV += TSeyeDir.xy * ( normalTex.a * PARALLAX_SCALE + PARALLAX_BIAS ); #endif From 18c002a21d9cb87ac33db74108ae4d1e91e3e52f Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 01:31:42 +0100 Subject: [PATCH 55/56] Fix an awful typo. --- components/terrain/material.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/terrain/material.cpp b/components/terrain/material.cpp index b421de5a28..511d45f412 100644 --- a/components/terrain/material.cpp +++ b/components/terrain/material.cpp @@ -220,9 +220,8 @@ namespace Terrain ++neededTextureUnits; // layer texture // Check if this layer has a normal map - if (mNormalMapping && !mLayerList[layerOffset].mNormalMap.empty()) + if (mNormalMapping && !mLayerList[layerIndex].mNormalMap.empty() && !renderCompositeMap) ++neededTextureUnits; // normal map - if (neededTextureUnits <= remainingTextureUnits) { // We can fit another! From 5fd98d7c3ad9edf31868953287881ce2bc3d8c7a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Dec 2013 01:41:36 +0100 Subject: [PATCH 56/56] Add an assertion --- components/terrain/material.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/terrain/material.cpp b/components/terrain/material.cpp index 511d45f412..5dcdb7fed8 100644 --- a/components/terrain/material.cpp +++ b/components/terrain/material.cpp @@ -334,6 +334,8 @@ namespace Terrain // Make sure the pass index is fed to the permutation handler, because blendmap components may be different p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(layerOffset))); + assert ((int)p->mTexUnits.size() == OGRE_MAX_TEXTURE_LAYERS - remainingTextureUnits); + layerOffset += numLayersInThisPass; } }