Набор функций для работы со строками
Скриншоты
Установка
- Скопировать триггер StringFunctions
Список функций
// Выводим сообщения
MessageTimed(string str, real time)
Message(string str)
MessageForPlayerTimed(player p, string str, real time)
MessageForPlayer(player p, string str)
// Очищаем строку сообщения
ClearTextMessagesForPlayer(player p)
// Получаем имя игрока
GetPlayerColorString(player p) -> string
GetPlayerNameColored(player p) -> string
// Обрезаем крайние символы
LTrim(string str, string found) -> string
RTrim(string str, string found) -> string
Trim(string str, string found) -> string
// Примеры
LTrim("---T-r-i-m---", "-"); // T-r-i-m---
RTrim("---T-r-i-m---", "-"); // ---T-r-i-m
Trim("---T-r-i-m---", "-"); // T-r-i-m
// Конвертируем boolean в строку
B2S(boolean b) -> string
// Примеры
B2S(true); // true
B2S(!true); // false
// Превращаем строку в равкод
S2RAW(string ObjectId) -> integer
// Пример
S2RAW("hfoo"); // 1751543663
// Превращаем равкод в строку
RAW2S(integer ObjectId) -> string
// Пример
RAW2S(1751543663); // hfoo
// Заменяем подстроку
StringReplaceCounted(string str, string found, string replace, integer count) -> string
StringReplace(string str, string found, string replace) -> string
// Примеры
StringReplaceCounted("old old old old old", "new", 2); // new new old old old
StringReplaceCounted("old old old old old", "new", -2); // old old old new new
StringReplace("old old old old old", "new"); // new new new new new
// Склоняем строку в зависимости от числа
Declension(integer number, string dec1, string dec4, string dec5);
/* Описание
number - число, от которого склонять
dec1 - вариант склонения для числа 1, например "предмет"
dec4 - вариант склонения для числа 4, например "предмета"
dec5 - вариант склонения для числа 5, например "предметов"
*/
// Пример
Declension(100500, "предмет", "предмета", "предметов") // предметов
// Склоняем строку в зависимости от числа с заменой подстроки и учётом нуля
Declenser(integer number, string found, string dec0, string dec1, string dec4, string dec5) -> string
/* Описание
number - число, от которого склонять
found - подстрока, которая будет заменена на number
dec0 - вариант строки для number == 0, например "Рюкзак пуст"
dec1 - вариант склонения для числа 1, например "В рюкзаке %count% предмет"
dec4 - вариант склонения для числа 4, например "В рюкзаке %count% предмета"
dec5 - вариант склонения для числа 5, например "В рюкзаке %count% предметов"
*/
// Пример
Declenser(
100500,
"%count%",
"Рюкзак пуст",
"В рюкзаке %count% предмет",
"В рюкзаке %count% предмета",
"В рюкзаке %count% предметов"
); // В рюкзаке 100500 предметов
Примеры использования
Unit
//! zinc
library Unit requires StringFunctions {
constant string SelectUnitHelp = "Чтобы узнать равкод |cffffff00юнита|r, просто выберите его.";
constant string AddUnitCommand = "-unit";
constant string AddUnitMessage = "Игрок %player-name% выбрал юнита: %unit-name%. %selected-count%.";
constant string AddUnitHelp = "Чтобы создать юнита наберите |cffffff00" + AddUnitCommand + " |cff909090####|r.";
constant string AddUnitEfect = "Objects\\Spawnmodels\\Human\\HCancelDeath\\HCancelDeath.mdl";
constant string AddUnitError = "|cffff0000Ошибка!|r Невозможно создать юнита |cffffff00%error%|r.";
public {
function GetUnitNameColored(unit u) -> string {
return "|cffffff00" + GetUnitName(u) + " |cff909090(" + RAW2S(GetUnitTypeId(u)) + ")|r";
}
}
function onInit(){
integer i;
trigger t;
Message(AddUnitHelp);
Message(SelectUnitHelp);
// Выбор юнита
t = CreateTrigger();
for(0 <= i < bj_MAX_PLAYER_SLOTS){
TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SELECTED, null);
}
TriggerAddAction(t, function(){
group g = CreateGroup();
player p = GetTriggerPlayer();
unit u;
integer count = 0;
string s;
SyncSelections();
GroupEnumUnitsSelected(g, p, null);
while (true){
u = FirstOfGroup(g);
if (u == null) { break; }
count = count + 1;
GroupRemoveUnit(g, u);
}
s = StringReplace(
AddUnitMessage,
"%player-name%",
GetPlayerNameColored(p)
);
s = StringReplace(
s,
"%unit-name%",
GetUnitNameColored(GetTriggerUnit())
);
s = StringReplace(
s,
"%selected-count%",
Declenser(
count,
"%count%",
"Юнитов не выбрано", // 0
"Выбран |cffffff00%count%|r юнит", // 1
"Выбрано |cffffff00%count%|r юнита", // 4
"Выбрано |cffffff00%count%|r юнитов" // 5
)
);
ClearTextMessagesForPlayer(p);
MessageForPlayer(p, s);
DestroyGroup(g); g = null;
});
// Создание юнита
t = CreateTrigger();
for(0 <= i < bj_MAX_PLAYER_SLOTS){
TriggerRegisterPlayerChatEvent(t, Player(i), AddUnitCommand, false);
}
TriggerAddAction(t, function(){
integer len = StringLength(AddUnitCommand) + 1;
string s = SubString(GetEventPlayerChatString(), len, len+4);
player p = GetTriggerPlayer();
unit u;
u = CreateUnit(p, S2RAW(s), GetRectCenterX(gg_rct_AddUnit), GetRectCenterY(gg_rct_AddUnit), GetRandomReal(0, 360));
if (u == null){
MessageForPlayer(p, StringReplace(AddUnitError, "%error%", s));
} else {
DestroyEffect(AddSpecialEffectTarget(AddUnitEfect, u, "origin"));
MessageForPlayer(p, "Создан юнит: " + GetUnitNameColored(u));
}
u = null;
});
}
}
//! endzinc
Item
//! zinc
library Item requires StringFunctions, Unit {
constant string ManipulatedString = "%unit-name% %event-name% %item-name%. %item-count%.";
constant string ManipulatedHelp = "Чтобы узнать равкод |cffffff00предмена|r, просто подберите его.";
constant string AddItemCommand = "-item";
constant string AddItemHelp = "Чтобы создать предмет наберите |cffffff00" + AddItemCommand + " |cff909090####|r.";
constant string AddItemError = "|cffff0000Ошибка!|r Невозможно создать предмет |cffffff00%error%|r.";
constant string AddItemEffect = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl";
public {
function GetItemNameColored(item i) -> string {
return "|cffffff00" + GetItemName(i) + " |cff909090(" + RAW2S(GetItemTypeId(i)) + ")|r";
}
}
function getItemCountString(unit u) -> string {
integer i, count = 0;
for (0 <= i < bj_MAX_INVENTORY){
if (UnitItemInSlot(u, i) != null){
count = count + 1;
}
}
return Declenser(
count,
"%count%",
"Рюкзак |c00fEBA0Eпуст|r", // 0
"В рюкзаке |c00FFFC01%count%|r предмет", // 1
"В рюкзаке |c00FFFC01%count%|r предмета", // 4
"В рюкзаке |c00FFFC01%count%|r предметов" // 5
);
}
function manipulatedActions(unit u, item i, string s){
string out;
player p = GetOwningPlayer(u);
TriggerSleepAction(0.01);
ClearTextMessagesForPlayer(p);
out = StringReplace(
ManipulatedString,
"%unit-name%",
GetUnitNameColored(u)
);
out = StringReplace(
out,
"%event-name%",
s
);
out = StringReplace(
out,
"%item-name%",
GetItemNameColored(i)
);
out = StringReplace(
out,
"%item-count%",
getItemCountString(u)
);
MessageForPlayer(GetOwningPlayer(u), out);
}
function onInit(){
integer i;
trigger t[];
Message(AddItemHelp);
Message(ManipulatedHelp);
// Получение|Потеря|Использование предмета
for (0 <= i <= 2){
t[i] = CreateTrigger();
}
for(0 <= i < bj_MAX_PLAYER_SLOTS){
TriggerRegisterPlayerUnitEvent(t[0], Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null);
TriggerRegisterPlayerUnitEvent(t[1], Player(i), EVENT_PLAYER_UNIT_DROP_ITEM, null);
TriggerRegisterPlayerUnitEvent(t[2], Player(i), EVENT_PLAYER_UNIT_USE_ITEM, null);
}
TriggerAddAction(t[0], function(){
manipulatedActions(GetTriggerUnit(), GetManipulatedItem(), "получает");
});
TriggerAddAction(t[1], function(){
manipulatedActions(GetTriggerUnit(), GetManipulatedItem(), "теряет");
});
TriggerAddAction(t[2], function(){
manipulatedActions(GetTriggerUnit(), GetManipulatedItem(), "использует");
});
// Создание предмта
t[3] = CreateTrigger();
for(0 <= i < bj_MAX_PLAYER_SLOTS){
TriggerRegisterPlayerChatEvent(t[3], Player(i), AddItemCommand, false);
}
TriggerAddAction(t[3], function(){
integer len = StringLength(AddItemCommand) + 1;
string s = SubString(GetEventPlayerChatString(), len, len+4);
player p = GetTriggerPlayer();
item i;
real x = GetRectCenterX(gg_rct_AddUnit);
real y = GetRectCenterY(gg_rct_AddUnit);
i = CreateItem(S2RAW(s),x , y);
if (i == null){
Message(StringReplace(AddItemError, "%error%", s));
} else {
DestroyEffect(AddSpecialEffect(AddItemEffect, x, y));
Message("Создан предмет: " + GetItemNameColored(i));
}
i = null;
});
for (0 <= i <= 3){
t[i] = null;
}
}
}
//! endzinc
Техничеcкие подробности
Код библиотеки
/**********************************************************
*
* ВСЁ, ЧТО НИЖЕ, ПРАВИТЬ НА СВОЙ СТРАХ И РИСК!!!
*
**********************************************************/
//! zinc
library StringFunctions {
constant real MessageDefaultTime = 60;
// RAW
constant string Alphabet = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
integer AlphabetValue[];
string AlphabetIndex[];
// Player Color
string PlayerColor[];
public {
// Message
function MessageTimed(string str, real time){ DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, time, str); }
function Message(string str) { MessageTimed(str, MessageDefaultTime); }
function MessageForPlayerTimed(player p, string str, real time){
integer i;
for(0 <= i < bj_MAX_PLAYER_SLOTS){
if (GetLocalPlayer() == Player(i)){
Message(str);
}
}
}
function MessageForPlayer(player p, string str){ MessageForPlayerTimed(p, str, MessageDefaultTime); }
// Clear Message
function ClearTextMessagesForPlayer(player p){ if (GetLocalPlayer() == p){ ClearTextMessages(); } }
// Player Name
function GetPlayerColorString(player p) -> string { return PlayerColor[GetPlayerId(p)]; }
function GetPlayerNameColored(player p) -> string { return GetPlayerColorString(p) + GetPlayerName(p) + "|r"; }
// Trim
function LTrim(string str, string found) -> string {
integer i, len = StringLength(str), s = 0;
for(0 <= i < len){
if (SubString(str, i, i + 1) == found){ s = s + 1;}
else { break; }
}
return SubString(str, s, len);
}
function RTrim(string str, string found) -> string {
integer i, len = StringLength(str), e = len;
for (len > i >= 0){
if (SubString(str, i, i + 1) == found){ e = e - 1; }
else { break; }
}
return SubString(str, 0, e);
}
function Trim(string str, string found) -> string {
str = LTrim(str, found);
str = RTrim(str, found);
return str;
}
// B2S
function B2S(boolean b) -> string {
if (b) { return "true"; }
return "false";
}
// RAW
function RAW2S(integer ObjectId) -> string {
integer i = 0, j = 4;
string result = "";
while(j > 0){
i = R2I(ObjectId/AlphabetValue[j]);
result = result + AlphabetIndex[i-31];
ObjectId = ObjectId - i*AlphabetValue[j];
j = j - 1;
}
return result;
}
function S2RAW(string ObjectId) -> integer {
integer length = StringLength(ObjectId);
integer result = 0;
integer i = 0;
integer j = 0;
string objectPart;
if (length != 4 ){ return 0; }
while (true) {
objectPart = SubString(ObjectId, j, j + 1);
while(true){
i = i + 1;
if (AlphabetIndex[i] == objectPart) { break; }
}
result = result + (i+31)*AlphabetValue[4-j];
j = j + 1;
i = 0;
if (j > 4) { break; }
}
return result;
}
// Replace
function StringReplaceCounted(string str, string found, string replace, integer count) -> string {
integer slen = StringLength(str);
integer flen = StringLength(found);
integer rlen = StringLength(replace);
integer i, counted = 0;
string s, c, out ="";
// check
if (slen == 0 || flen == 0 || flen > slen){ return str; }
if (count >= 0){ // from left
i = -1;
while (i < slen - flen){
i = i + 1;
s = SubString(str, i, i+flen);
c = SubString(str, i, i+1);
if (s == found && (count == 0 || counted < count)){
i = i - 1 + flen;
counted = counted + 1;
out = out + replace;
} else {
out = out + c;
}
}
out = out + SubString(str, i+1, i+1+flen);
} else { // from right
i = slen;
while (i >= flen){
i = i - 1;
s = SubString(str, i+1-flen, i+1);
c = SubString(str, i, i+1);
if (s == found && counted > count){
i = i + 1 - flen;
counted = counted - 1;
out = replace + out;
} else {
out = c + out;
}
}
out = SubString(str, 0, i) + out;
}
return out;
}
function StringReplace(string str, string found, string replace) -> string {
return StringReplaceCounted(str, found, replace, 0);
}
// Declension
function Declension(integer number, string dec1, string dec4, string dec5) -> string {
integer i;
number = ModuloInteger(IAbsBJ(number), 100);
if (number >= 11 && number <= 19) {
return dec5;
} else {
i = ModuloInteger(number, 10);
if (i == 1){
return dec1;
} else if (i >= 2 && i<= 4){
return dec4;
}
return dec5;
}
return dec1;
}
function Declenser(integer number, string found, string dec0, string dec1, string dec4, string dec5) -> string {
string out;
if (number == 0){
out = dec0;
} else {
out = Declension(number, dec1, dec4, dec5);
}
return StringReplace(out, found, I2S(number));
}
}
function onInit(){
integer i;
// Player Color
PlayerColor[0] = "|c00FF0303"; // red
PlayerColor[1] = "|c000042FF"; // blue
PlayerColor[2] = "|c001CE6B9"; // teal
PlayerColor[3] = "|c00540081"; // purple
PlayerColor[4] = "|c00FFFC01"; // yellow
PlayerColor[5] = "|c00fEBA0E"; // orange
PlayerColor[6] = "|c0020C000"; // green
PlayerColor[7] = "|c00E55BB0"; // pink
PlayerColor[8] = "|c00959697"; // gray
PlayerColor[9] = "|c007EBFF1"; // lightblue
PlayerColor[10] = "|c00106246"; // darkgreen
PlayerColor[11] = "|c004E2A04"; // brown
PlayerColor[12] = "|cff909090";
PlayerColor[13] = "|cff909090";
PlayerColor[14] = "|cff909090";
// RAW
i = 0;
while (true){
i = i + 1;
AlphabetIndex[i] = SubString(Alphabet, i-1, i);
if (AlphabetIndex[i] == "") { break; }
}
AlphabetValue[1] = 1;
AlphabetValue[2] = 256;
AlphabetValue[3] = 256 * 256;
AlphabetValue[4] = 256 * 256 * 256;
}
}
//! endzinc
Если понадобятся новые функции, пишите в комментариях
NazarPunk, либо в заранее занести в массив
library GamePlayers
endlibrary
а где функция для получение нужного параметра например "text,text,new" каждый запятой или указаный знак возврашали массив explode(",", "text,text,new", 2) вернет new нумерация с 0
NazarPunk, и главное строка кешировать чтобы повторно цикл не проходить если надо получить параметры несколько раз =) если инпут ранее было то возврашаем старый массив это глобальный делай так
Ред. nazarpunk
string s1 = StringExplodeSearch(",", "1,2,3,4,5,6", 0); Сработает 1 раз цикл
string s1 = StringExplodeSearch(",", "1,2,3,4,5,6", 3); из кеша
string s1 = StringExplodeSearch(",", "1,2,3,4,5,6", 5); из кеша
string s1 = StringExplodeSearch(",", "6,5,4,3,2,1", 0); новый инпут значит обнуляем кеш и проходим цикл
Ред. nazarpunk
pro100master:
И ещё в документации это отразить нужно будет(