Назад

Проблема с переменными.

Автор: ????: Дата: 02.02.2011

В общем есть некий скрипт, в нём массив, который заполняется автоматически и передаётся в другой скрипт. Мне надо следующее:
1) Что бы этот массив привязался только к чару.
2) Что бы после перезахода или рестарта серва, массив не потерялся.
3) Он должен быть целочисленным.
3) Что бы мап-сервер не ругался на него :D
В общем сам массив:
setarray Mobs[getarraysize(Mobs)],getarg(0);
В доках нашёл следующее:
name - permanent character integer variable
name$ - permanent character string variable
Пробовал и Mobs и Mobs$. Мап сервер постоянно ругался на эту переменную, раньше использовал $@Mobs, но понял что мне такая переменная не нужна, но с ней работало.
А ругается так:

[Error]: script:getarraysize: illegal scope
[Debug]: Data: variable name='Mobs'
[Debug]: Source (NPC): ┴ырсырсыр2 at prontera (153,153)


Причём ругается, не при загрузке, а при разговоре с данным нпц, когда он как раз таки должен занести ID моба в массив.
Дак что мне в данном случает делать, уважаемые знатаки скриптинга, поскажите.

Автор: Мяфк: Дата: 02.02.2011

Да это-то тут причём. Раз при $@Mobs не ругался, а при Mobs ругается, всё дело в типе переменной.

Автор: Кеник: Дата: 02.02.2011

Это были танцы с бубном :D

Давай так попробуем...

name = reference_getname(data);
if( not_array_variable(*name) )
{
ShowError("script:getarraysize: illegal scope\n");
script_reportdata(data);
script_pushnil(st);
st->state = END;
return 1;// not supported
}

Автор: Мяфк: Дата: 02.02.2011

Ты предлагаешь сорцы изменить?

Автор: Кеник: Дата: 02.02.2011

Я предлагаю почитать кусок кода - мб в этом ошипка кроется :D На самом деле я не силен в С++ и в сорсы стараюсь не лезть лишний раз, поэтому лишь слегка пытаюсь помочь, но не более того.... Все равно других вариантов пока нет :D

Автор: Кеник: Дата: 02.02.2011

if( not_array_variable(*name) )


Если переменная - не массив, так? Мб ты определяешь её как переменнуб, а потом пытаешься забить как массив?

Автор: Мяфк: Дата: 02.02.2011

Нет, везде она идёт как: setarray

Автор: Кеник: Дата: 02.02.2011

А переменная "Mobs" точно нигде не используется? Мб ты пытаешься назначить массивом уже существующую переменную?

Автор: Jarek: Дата: 02.02.2011

Как я и догадывался.
Нашел на еа

eAthena doesn't have support for character-stored arrays... This isn't cool.

Печаль

Автор: Alort: Дата: 02.02.2011

Цитата Jarek;32383:
Как я и догадывался.
Нашел на еа

Печаль


Типо только переменные можно привязать к чару?

Автор: Кеник: Дата: 02.02.2011

Ага. Массивы не получится..

Автор: Gremlin: Дата: 02.02.2011

имхо легче через скл сделать, а так вот нужный кусок из доков, где приведено, какие типы переменных поддерживаются массивами в афине

Resume of the allowed variable and array scopes
------ -- --- ------- -------- --- ----- ------

+==========+======+=======+
|VarType | Norm | Array |
+==========+======+=======+
|$Str$ | OK! | OK! |
+----------+------+-------+
|$@Str$ | OK! | OK! |
+----------+------+-------+
|@Str$ | OK! | OK! |
+----------+------+-------+
|#Str$ | OK! | FAIL! |
+----------+------+-------+
|Str$ | OK! | FAIL! |
+----------+------+-------+
|$Int | OK! | OK! |
+----------+------+-------+
|$@Int | OK! | OK! |
+----------+------+-------+
|@Int | OK! | OK! |
+----------+------+-------+
|#Int | OK! | FAIL! |
+----------+------+-------+
|Int | OK! | FAIL! |
+----------+------+-------+
|.Str$ | OK! | OK! |
+----------+------+-------+
|.Int | OK! | OK! |
+----------+------+-------+
|.@Str$ | OK! | OK! |
+----------+------+-------+
|.@Int | OK! | OK! |
+----------+------+-------+

Автор: Jarek: Дата: 02.02.2011

Да,
Но оно и правильно, неизвестно какого объема массив скриптер хочет сохранить, а количество переменных не резиновое, а массив скорее всего займет столько места, сколько в массиве элементов.

Автор: Мяфк: Дата: 02.02.2011

Мда, реально печаль... Единсвенный вариант теперь в базу писать, либо вообще новую таблицу создать, где будет чар айди и мои строки с массивами, хз в общем..

Автор: Starrk: Дата: 02.03.2011

В script_commands.txt находится не только описание скриптовых функций, в самом начале куча интересной инфы:


Variables
---------

The meat of every programming language is variables - places where you store
data.

Variables are divided into and uniquely identified by the combination of:
prefix - determines the scope and extent (or lifetime) of the variable
name - an identifier consisting of '_' and alphanumeric characters
postfix - determines the type of the variable: integer or string

Scope can be:
global - global to all servers
local - local to the server
account - attached to the account of the character identified by RID
character - attached to the character identified by RID
npc - attached to the NPC
scope - attached to the scope of the instance

Extent can be:
permanent - They still exist when the server resets.
temporary - They cease to exist when the server resets.

[COLOR=DarkOrange]Prefix: scope and extent
nothing - A permanent variable attached to the character, the default variable
type. They are stored with all the account data in "save\athena.txt"
in TXT versions and in the SQL versions in the `global_reg_value`
table using type 3.
"@" - A temporary variable attached to the character.
SVN versions before 2094 revision and RC5 version will also treat
'l' as a temporary variable prefix, so beware of having variable
names starting with 'l' if you want full backward compatibility.
"$" - A global permanent variable.
They are stored in "save\mapreg.txt" or database table `mapreg`,
depending on server type.
"$@" - A global temporary variable.
This is important for scripts which are called with no RID
attached, that is, not triggered by a specific character object.
"." - A NPC variable.
They exist in the NPC and disappear when the server restarts or the
NPC is reloaded. Can be accessed from inside the NPC or by calling
'getvariableofnpc'.
".@" - A scope variable.
They are unique to the instance and scope. Each instance has it's
own scope that ends when the script ends. Calling a function with
callsub/callfunc starts a new scope, returning from the function
ends it. When a scope ends, it's variables are converted to values
('return .@var;' returns a value, not a reference).
"#" - A permanent local account variable.
They are stored with all the account data in "save\accreg.txt" in
TXT versions and in the SQL versions in the 'global_reg_value'
table using type 2.
"##" - A permanent global account variable stored by the login server.
They are stored in "save\account.txt" and in the SQL versions in the
'global_reg_value' table, using type 1. The only difference you will
note from normal # variables is when you have multiple char-servers
connected to the same login server. The # variables are unique to
each char-server, while the ## variables are shared by all these
char-servers.

Postfix: integer or string

nothing - integer variable, can store positive and negative numbers, but only
whole numbers (so don't expect to do any fractional math)
'$' - string variable, can store text


Examples:
name - permanent character integer variable
name$ - permanent character string variable
@name - temporary character integer variable
@name$ - temporary character string variable
$name - permanent global integer variable
$name$ - permanent global string variable
$@name - temporary global integer variable
$@name$ - temporary global string variable
.name - NPC integer variable
.name$ - NPC string variable
.@name - scope integer variable
.@name$ - scope string variable
#name - permanent local account integer variable
#name$ - permanent local account string variable
##name - permanent global account integer variable
##name$ - permanent global account string variable
[/COLOR]

If a variable was never set, it is considered to equal zero for integer
variables or an empty string ("", nothing between the quotes) for string
variables. Once you set it to that, the variable is as good as forgotten
forever, and no trace remains of it even if it was stored with character or
account data.

Some variables are special, that is, they are already defined for you by the
scripting engine. You can see the full list somewhere in 'db/const.txt', which
is a file you should read, since it also allows you to replace lots of numbered
arguments for many commands with easier to read text. The special variables most
commonly used are all permanent character-based variables:

StatusPoint - Amount of status points remaining.
BaseLevel - Current base level
SkillPoint - Amount of skill points remaining
Class - Current job
Upper - 1 if the character is an advanced job class.
Zeny - Current amount of Zeny
Sex - Character's gender, 0 if female, 1 if male.
Weight - The weight the character currently carries.
MaxWeight - The maximum weight the character can carry.
JobLevel - Character's job level
BaseExp - The amount of base experience points the character has.
Notice that it's zero (or close) if the character just got a level.
JobExp - Same for job levels
NextBaseExp - Amount of experience points needed to reach the next base level.
NextJobExp - Same for job levels.
Hp - Current amount of hit points.
MaxHp - Maximum amount of hit points.
Sp - Current spell points.
MaxSp - Maximum amount of spell points.
BaseJob - This is sneaky, apparently meant for baby class support.
This will supposedly equal Job_Acolyte regardless of whether the
character is an acolyte or a baby acolyte, for example.
Karma - The character's karma. Karma system is not fully functional, but
this doesn't mean this doesn't work at all. Not tested.
Manner - The character's manner rating. Becomes negative if the player
utters words forbidden through the use of 'manner.txt' client-side
file.

While these behave as variables, do not always expect to just set them - it is
not certain whether this will work for all of them. Whenever there is a command
or a function to set something, it's usually preferable to use that instead. The
notable exception is Zeny, which you can and often will address directly -
setting it will make the character own this number of Zeny.
If you try to set Zeny to a negative number, the script will be terminated with an error.

Strings
-------

To include symbol '"' in a string you should use prefix '\"'


Arrays
------

Arrays (in eAthena at least) are essentially a set of variables going under the
same name. You can tell between the specific variables of an array with an
'array index', a number of a variable in that array:

[]

Variables stored in this way, inside an array, are also called 'array elements'.
Arrays are specifically useful for storing a set of similar data (like several
item IDs for example) and then looping through it. You can address any array
variable as if it was a normal variable:

set @arrayofnumbers[0],1;

You can also do sneaky things like using a variable (or an expression, or even a
value from an another array) to get at an array value:

set @x,100;
set @arrayofnumbers[@x],10;

This will make @arrayofnumbers[100] equal to 10.

Notice that index numbering always starts with 0. Arrays cannot hold more than
128 variables. (So the last one can't have a number higher than 127)

And array indexes probably can't be negative. Nobody tested what happens when
you try to get a negatively numbered variable from an array, but it's not going
to be pretty. :)

Arrays can naturally store strings:

@menulines$[0] is the 0th element of the @menulines$ array of strings. Notice
the '$', normally denoting a string variable, before the square brackets that
denotes an array index.

Resume of the allowed variable and array scopes
------ -- --- ------- -------- --- ----- ------

[COLOR=DarkOrange]+==========+======+=======+
|VarType | Norm | Array |
+==========+======+=======+
|$Str$ | OK! | OK! |
+----------+------+-------+
|$@Str$ | OK! | OK! |
+----------+------+-------+
|@Str$ | OK! | OK! |
+----------+------+-------+
|#Str$ | OK! | FAIL! |
+----------+------+-------+
|Str$ | OK! | FAIL! |
+----------+------+-------+
|$Int | OK! | OK! |
+----------+------+-------+
|$@Int | OK! | OK! |
+----------+------+-------+
|@Int | OK! | OK! |
+----------+------+-------+
|#Int | OK! | FAIL! |
+----------+------+-------+
|Int | OK! | FAIL! |
+----------+------+-------+
|.Str$ | OK! | OK! |
+----------+------+-------+
|.Int | OK! | OK! |
+----------+------+-------+
|.@Str$ | OK! | OK! |
+----------+------+-------+
|.@Int | OK! | OK! |
+----------+------+-------+
[/COLOR]

Variable References
-------------------

//##TODO



Operators
---------

Operators are things you can do to variables and numbers. They are either the
common mathematical operations or conditional operators

+ - will add two numbers. If you try to add two strings, the result will be a
string glued together at the +. You can add a number to a string, and the
result will be a string. No other math operators work with strings.
- - will subtract two numbers.
* - will multiply two numbers.
/ - will divide two numbers. Note that this is an integer division, i.e.
7/2 is not equal 3.5, it's equal 3.
% - will give you the remainder of the division. 7%2 is equal to 1.

There are also conditional operators. This has to do with the conditional
command 'if' and they are meant to return either 1 if the condition is satisfied
and 0 if it isn't. (That's what they call 'boolean' variables. 0 means 'False'.
Anything except the zero is 'True' Odd as it is, -1 and -5 and anything below
zero will also be True.)

You can compare numbers to each other and you compare strings to each other, but
you can not compare numbers to strings.

== - Is true if both sides are equal. For strings, it means they are the same.
>= - True if the first value is equal to, or greater than, the second value.
<= - True if the first value is equal to, or less than, the second value
> - True if the first value greater than the second value
< - True if the first value is less than the second value
!= - True if the first value IS NOT equal to the second one

Examples:

1==1 is True.
1<2 is True while 1>2 is False.
@x>2 is True if @x is equal to 3. But it isn't true if @x is 2.

Only '==' and '!=' have been tested for comparing strings. Since there's no way
to code a seriously complex data structure in this language, trying to sort
strings by alphabet would be pointless anyway.

Comparisons can be stacked in the same condition:

&& - Is True if and only if BOTH sides are true.
('1==1 && 2==2' is true. '2==1 && 1==1' is false.)
|| - Is True if either side of this expression is True.

1==1 && 2==2 is True.
1==1 && 2==1 is False.
1==1 || 2==1 is True.

[COLOR=DarkOrange]Logical bitwise operators work only on numbers, and they are the following:

<< - Left shift.
>> - Right shift.
Left shift moves the binary 1(s) of a number n positions to the left,
which is the same as multiplying by 2, n times.
In the other hand, Right shift moves the binary 1(s) of a number n positions
to the right, which is the same as dividing by 2, n times.
Example:
set b,2;
set a, b << 3;
mes a;
set a, a >> 2;
mes a;
The first mes command would display 16, which is the same as 2 x (2 x 2 x 2) = 16.
The second mes command would display 4, which is the same as 16 / 2 = 8. 8 / 2 = 4.
& - And.
| - Or.
The bitwise operator AND (&) is used to test two values against each other,
and results in setting bits which are active in both arguments. This can
be used for a few things, but in eAthena this operator is usually used to
create bit-masks in scripts.

The bitwise operator OR (|)sets to 1 a binary position if the binary position
of one of the numbers is 1. This way a variable can hold several values we can check,
known as bit-mask. A variable currently can hold up to 32 bit-masks (from position 0
to position 1). This is a cheap(skate) and easy way to avoid using arrays to store several checks
that a player can have.

A bit-mask basically is (ab)using the variables bits to set various options in
one variable. With the current limit if variables it is possible to store 32
different options in one variable (by using the bits on position 0 to 31).

Example(s):
- Basic example of the & operator, bit example:
10 & 2 = 2
Why? :
10 = 2^1 + 2^3 (2 + 8), so in bits, it would be 1010
2 = 2^1 (2), so in bits (same size) it would be 0010
The & (AND) operator sets bits which are active (1) in both arguments, so in the
example 1010 & 0010, only the 2^1 bit is active (1) in both. Resulting in the bit
0010, which is 2.
- Basic example of creating and using a bit-mask:
set @options,2|4|16; //(note: this is the same as 2+4+16, or 22)
if (@options & 1) mes "Option 1 is activated";
if (@options & 2) mes "Option 2 is activated";
if (@options & 4) mes "Option 3 is activated";
if (@options & 8) mes "Option 4 is activated";
if (@options & 16) mes "Options 5 is activated";
This would return the messages about option 2, 3 and 5 being shown (since we've set
the 2,4 and 16 bit to 1).
^ - Xor.
The bitwise operator XOR (eXclusive OR) sets a binary position to 0 if both
numbers have the same value in the said position. On the other hand, it
sets to 1 if they have different values in the said binary position.
This is another way of setting and unsetting bits in bit-masks.

Example:
- First let's set the quests that are currently in progress:
set inProgress,1|8|16; // quest 1,8 and 16 are in progress
- After playing for a bit, the player starts another quest:
if( inProgress&2 == 0 ){
// this will set the bit for quest 2 (inProgress has that bit set to 0)
set inProgress,inProgress^2;
mes "Quest 2: find a newbie and be helpful to him for an hour.";
close;
}
- After spending some time reading info on Xor's, the player finally completes quest 1:
if( inProgress&1 && isComplete ){
// this will unset the bit for quest 1 (inProgress has that bit set to 1)
set inProgress,inProgress^1;
mes "Quest 1 complete!! You unlocked the secrets of the Xor dynasty, use them wisely.";
close;
}

Unary operators with only with a single number, which follows the operator, and

are following:

- - Negation.
The sign of the number will be reversed. If the number was positive, it will
become negative and vice versa.

Example:
set .@myvar,10;
mes "Negative 10 is "+(-.@myvar);

! - Logical Not.
Reverses the boolean result of an expression. True will become false and
false will become true.

Example:
if(!callfunc("F_dosomething"))
{
mes "Doing something failed.";
close;
}

~ - Bitwise Not.
Reverses each bit in a number, also known as one's complement. Cleared bits
are set, and set bits are cleared.

Example:
- Ensure, that quest 2 is disabled, while keeping all other active, if they are.
set inProgress,inProgress&(~2); // same as set inProgress,inProgress&0xfffffffd

Ternary operators take three expressions (numbers, strings or boolean), and are

following:

?: - Conditional operator
Very useful e.g. to replace

[/COLOR] [COLOR=DarkOrange] if(Sex) mes "..."; else mes "...";

clauses with simple

mes "Welcome, " + (Sex?"Mr.":"Mrs.") + " " + strcharinfo(0);

or to replace any other simple if-else clauses. It might be worth
mentioning that ?: has low priority and has to be enclosed with
parenthesis in most (if not all) cases.
[/COLOR]
Наиболее нужное выделено.

ЗЫ Советую всем также почитать последнюю часть про побитовые и условный операторы.

Автор: Кеник: Дата: 02.03.2011

Капитан очевидность с нами =/ Я бы минусовал за такие посты, но тут только пасипки(

Автор: Мяфк: Дата: 02.03.2011

Угу, посмотри первый пост, я писал про это:
name - permanent character integer variable
name$ - permanent character string variable
Что ни одна из этих переменных не работает с массивом..

Автор: Кеник: Дата: 02.03.2011

Ну я к тому и говорил) Вообще отсылка в доки - это полезно, но не так, как сейчас. Такое ощущение, что ему нечего сказать, а сказать что-нибудь надо :D