Aschbourne_PRC8/_module/nss/mk_editor_main.nss
Jaysyn904 903f023230 Major update
Created top hak for crafting dialog.  Moved Bioware creature abilities to top hak.  Fixed DMFI wand handouts.  Added DMFI language handouts.  Added CCOH 6.  Disabled PC corpse system.  Modified new player startup system.  Full compile.  Updated release archive.
2024-09-17 13:24:57 -04:00

1135 lines
33 KiB
Plaintext
Raw Permalink Blame History

#include "mk_inc_generic"
#include "mk_inc_time"
#include "mk_inc_tools_s"
#include "mk_inc_pixel"
#include "mk_inc_editor"
#include "mk_inc_editor_c"
#include "mk_inc_delimiter"
////////////////////////////////////////////////////////////////////////////
// used custom tokens:
// - 19999: text
// - 19998: cursor position
// - 19997: length of text
// - 19996: block on
// - 19995: headline
// - 19992: -------...--------
// - 19991: colors (colored text 'colors')
//
// - 19990: </c>
// - 19989: color of 'OK' button
// - 19988: color of 'Color Off'
// - 19987: editor window: color head lines, foot lines
// - 19986: color of button 'Color Off'
// - 19985: color of 'Cancel' button
// - 19984: key color
// - 19983: insert color
// - 19982: color of 'Back to main menu' button
// - 19981: color of 'Help' button
// - 19980: color of 'Load/Save' button
//
// - 19951,...
// - 19970: color names
// return a if a<b or b==-1 otherwise it returns b
int _min(int a, int b);
// return a if a>b or b==-1 otherwise it returns b
int _max(int a, int b);
// deletes the text between nStart and nEnd and returns the result
string DeleteBlock(string sText, int nStart, int nEnd);
// returns the text between nStart and nEnd
string CopyBlock(string sText, int nStart, int nEnd);
// inserts sInsert at position nPos into sText and returns the result
string InsertText(string sText, int nPos, string sInsert, int nMaxLength);
// returns sColorTag + sText + </c>
string AddColorTag(string sText, string sColorTag);
// creates the editor 'screen'
void CreateDisplay(object oPC, string sText, int nCursor, int nBlock);
// returns true if block mode is on,
// block mode is on if (nBlock!=-1) and (nBlock!=nCursor)
int IsBlockMarked(int nCursor, int nBlock);
// initializes the custom tokens
void InitCustomTokens();
// sets the custom tokens for the color names used by the color sub menu
void SetColorMenuStrings();
string GetFileSlotVarName(int nSlot);
// LineFeedMode: 0=ignore, 1=cut, 2=remove
string LoadTextFromSlot(object oObject, int nSlot, int nMaxLength=-1, int nLineFeedMode=0);
void SaveTextToSlot(object oObject, int nSlot, string sText);
// creates a line of the file menu
string CreateFileMenuText(object oObject, int bSave, int nSlot);
// sets the custom tokens for load/save slots used by the load/save sub menu
void SetFileMenuStrings(object oObject);
// moves the cursor one character to the right,
// basically a simple 'nCursor++' unless the character right to the cursor
// is a tag (color tag or </c>). Then the cursor jumps over the tag.
int IncCursor(string sText, int nCursor, int nDelta=1);
// moves the cursor one character to the left,
// basically a simple 'nCursor--' unless the character left to the cursor
// is a tag (color tag or </c>). Then the cursor jumps over the tag.
int DecCursor(string sText, int nCursor, int nDelta=1);
// reads a color name from a 2DA file (default = mk_colors.2da).
string GetColorName(int iColor);
// reads a color tag from a 2DA file (default = mk_colors.2da).
string GetColorTag(int iColor);
// if bUsePlayerChatEvent is FALSE (single player mode) it returns
// GetPCChatMessage().
// if bUsePlayerChatEvent is TRUE (multi player mode) it returns
// GetLocalString(oPC, g_varEditorChatMessageString).
// The variable should be set inside OnPlayerChatEvent.
string GetPCChatMessageEx(object oPC, int bUsePlayerChatEvent);
void IncLocalInt(object oObject, string sVarName, int n=1);
/*
// returns true if sText starts with a 'color tag'
// (something like <cXXX>).
int IsColorTag(string sText);
// returns true if sText starts with the 'close color tag' (</c>).
int IsCloseTag(string sText);
*/
struct mk_lastAction
{
int nAction;
float fTimeStamp;
};
// stores nAction and the current time on the oObject
void StoreAction(object oObject, int nAction);
// reads nAction and time passed as time stamp from oObject
struct mk_lastAction GetLastAction(object oObject);
// calculates the cursor speed
int CalculateCursorSpeed(object oObject, int nAction);
// the 'menus'...
const int nMainMenu = 0;
const int nColorMenu = 1;
const int nFileMenu = 2;
// the 'keys'...
const int nKeyPos1 = 1;
const int nKeyCursorLeft = 2;
const int nKeyCursorRight = 3;
const int nKeyEnd = 4;
const int nKeyShiftPos1 = 5;
const int nKeyShiftCursorLeft = 6;
const int nKeyShiftCursorRight = 7;
const int nKeyShiftEnd = 8;
const int nKeyInsert = 9;
const int nKeyDelete = 10;
const int nKeyBackspace = 11;
const int nKeyCtrlInsert = 12;
const int nKeyShiftInsert = 13;
const int nKeyShiftDelete = 14;
const int nKeyReturn = 15;
const int nKeyColorMenu = 16;
const int nKeyFileMenu = 17;
const int nNumberOfLoadSaveSlots = 5;
const int nMaxTextDisplayLength = 25;
const string sLineOnScreen = "-------------------------------------------";
const string sColoredColor = "<c<> >C</c><c<><63> >o</c><c <20> >l</c><c <20><>>o</c><c <20>>r</c><c<> <20>>s</c>";
const string sEmptyLine = " ";
const string sEditorHeadLine = "IGTE 1.02 - Text:";
int StartingConditional()
{
object oPC = GetPCSpeaker();
// read the current text
string sText = GetLocalString(oPC, g_varEditorBuffer);
// read the clipboard
string sClipboard = GetLocalString(oPC, g_varEditorClipboard);
// read the cursor position
int nCursor = GetLocalInt(oPC, g_varEditorCursor);
// read the block position
int nBlock = GetLocalInt(oPC, g_varEditorBlock);
// read the menu mode
int nMenuMode = GetLocalInt(oPC, g_varEditorMenuMode);
// read the editor settings, these setings should be set in the
// script that starts the editor
int nMaxLength = GetLocalInt(oPC, g_varEditorMaxLength);
int bSingleLine = GetLocalInt(oPC, g_varEditorSingleLine);
int bDisableColors = GetLocalInt(oPC, g_varEditorDisableColors);
int bDisableBlock = GetLocalInt(oPC, g_varEditorDisableBlock);
int bUsePlayerChatEvent = GetLocalInt(oPC, g_varEditorUseOnPlayerChatEvent);
int bDisableLoadSave = GetLocalInt(oPC, g_varEditorDisableLoadSave);
int nAction;
int bInitialize = GetLocalInt(oPC, g_varEditorInit);
// if bInitialize is TRUE we have to initialize the editor
if (bInitialize)
{
SetLocalInt(oPC, g_varEditorInit, 0);
// initialize the custom tokens
InitCustomTokens();
// indicate that the editor is running
// the variable g_varEditorRunning can/should be used in the
// OnPlayerChatEvent.
// if it is already set then the last time the editor was
// closed using the 'escape' key
if (GetLocalInt(oPC, g_varEditorRunning)==0)
{
SetLocalInt(oPC, g_varEditorRunning, 1);
// inc the number of editor instances currently running
IncLocalInt(GetModule(), g_varEditorCounter);
}
// execute an OnInit script (optional)
MK_Editor_ExecuteScript(oPC, g_varEditorOnInit);
// read the starting text from a variable stored on the user
sText=GetLocalString(oPC, g_varEditorText);
// block mode is off
nBlock = -1;
// move the cursor behind the last character
nCursor = GetStringLength(sText);
// the main menu is shown
nMenuMode = 0;
nAction = -1;
}
else
{
// we're not in the init mode so lets read the key pressed by the
// user (that is the dialog option selected by the user).
nAction = MK_GenericDialog_GetAction(TRUE);
}
// MK_DEBUG_TRACE("ColorMode = "+IntToString(nColorMode)
// +", Action = "+IntToString(nAction));
string sInsert;
int nCursorSpeed;
switch (nMenuMode)
{
case nMainMenu:
// we don't have cursor up/down so moving the cursor in a
// larger text can become quite tedious. That's why we move
// the cursor by more than one character if time passed between
// two cursor left/right is very small
nCursorSpeed = CalculateCursorSpeed(oPC, nAction);
switch (nAction)
{
case nKeyPos1: // pos 1
// move cursor in front of first character, block mode off
nCursor = 0;
nBlock = -1;
break;
case nKeyCursorLeft: // cursor left
// move cursor on character to the left, block mode off
nCursor = DecCursor(sText, nCursor, nCursorSpeed);
nBlock = -1;
break;
case nKeyCursorRight: // cursor right
// move cursor on character to the right, block mode off
nCursor = IncCursor(sText, nCursor, nCursorSpeed);
nBlock = -1;
break;
case nKeyEnd: // end
// move cursor behind the last character, block mode off
nCursor = GetStringLength(sText);
nBlock = -1;
break;
case nKeyShiftPos1:
// turn block mode on and move cursor in front of first character
if (nBlock==-1) nBlock = nCursor;
nCursor = 0;
break;
case nKeyShiftCursorLeft: // shift cursor left
// turn block mode on and move cursor one character to the left
if (nBlock==-1) nBlock = nCursor;
nCursor = DecCursor(sText, nCursor, nCursorSpeed);
break;
case nKeyShiftCursorRight: // shift cursor right
// turn block mode on and move cursor one character to the right
if (nBlock==-1) nBlock = nCursor;
nCursor = IncCursor(sText, nCursor, nCursorSpeed);
break;
case nKeyShiftEnd:
// turn block mode on and move cursor behind the last character
if (nBlock==-1) nBlock = nCursor;
nCursor = GetStringLength(sText);
break;
case nKeyDelete: // delete
if (IsBlockMarked(nCursor, nBlock))
{
// delete the marked block and get the new cursor
// position
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
else
{
// calculate the position right to the cursor position
// and delete the text between the cursor and this position.
// Looks complicated but is necessary because we don't
// want to delete just leading '<' of a (color) tag.
// We want to delete the whole tag of course.
int nCursorQ = IncCursor(sText, nCursor);
sText = DeleteBlock(sText,nCursor,nCursorQ);
}
nBlock = -1;
break;
case nKeyBackspace: // backspace
if (IsBlockMarked(nCursor, nBlock))
{
// delete the marked block and get the new cursor
// position
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
else
{
// calculate the position left to the cursor position
// and delete the text between the cursor and this position.
// This is also the new cursor position.
// Looks complicated but is necessary because we don't
// want to delete just closing '>' of a (color) tag.
// We want to delete the whole tag of course.
int nCursorQ = DecCursor(sText, nCursor);
sText = DeleteBlock(sText,nCursorQ,nCursor);
nCursor = nCursorQ;
}
nBlock = -1;
break;
case nKeyShiftDelete: // shift delete
if (IsBlockMarked(nCursor, nBlock))
{
// If a block is marked we copy that block to the
// clibboard and then we delete the block.
sClipboard = CopyBlock(sText, nBlock, nCursor);
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
else
{
// If no block is marked this is the same as 'backspace'
int nCursorQ = DecCursor(sText, nCursor);
sText = DeleteBlock(sText,nCursorQ,nCursor);
nCursor = nCursorQ;
}
nBlock = -1;
break;
case nKeyCtrlInsert:
if (IsBlockMarked(nCursor, nBlock))
{
// If a block is marked we copy that block to the clipboard.
sClipboard = CopyBlock(sText, nBlock, nCursor);
}
break;
case nKeyShiftInsert:
// If a block is marked we delete that block.
if (IsBlockMarked(nCursor, nBlock))
{
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
// Turn block mode off
nBlock=-1;
// Insert the clipboard into the text at the cursor position.
// The new cursor position is behind the just inserted text.
{
// we don't know how many characters get added so
// nCursor += GetStringLength(sClipboard)
// might be wrong.
int nLenOld = GetStringLength(sText);
sText = InsertText(sText, nCursor, sClipboard, nMaxLength);
int nLenNew = GetStringLength(sText);
nCursor += (nLenNew - nLenOld);
}
break;
case nKeyInsert: // insert text
// If a block is marked we delete that block.
if (IsBlockMarked(nCursor, nBlock))
{
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
nBlock=-1;
// If the user has entered some text into the chat line
// and has pressed the enter key we can read that text
// and insert it into the editor.
sInsert = GetPCChatMessageEx(oPC, bUsePlayerChatEvent);
{
// we don't know how many characters get added so
// nCursor += GetStringLength(sInsert)
// might be wrong.
int nLenOld = GetStringLength(sText);
sText = InsertText(sText, nCursor, sInsert, nMaxLength);
int nLenNew = GetStringLength(sText);
nCursor += (nLenNew - nLenOld);
}
break;
case nKeyReturn: // return
// If a block is marked we delete that block.
if (IsBlockMarked(nCursor, nBlock))
{
sText = DeleteBlock(sText, nBlock, nCursor);
nCursor = _min(nBlock, nCursor);
}
nBlock=-1;
// We insert line feed at cursor position
sInsert = "\n";
{
// we don't know how many characters get added so
// nCursor += GetStringLength(sInsert)
// might be wrong.
int nLenOld = GetStringLength(sText);
sText = InsertText(sText, nCursor, sInsert, nMaxLength);
int nLenNew = GetStringLength(sText);
if (nLenNew>nLenOld)
{
nCursor = IncCursor(sText, nCursor);
}
}
break;
case nKeyColorMenu: // color
// Activate the color menu
nMenuMode = nColorMenu;
break;
case nKeyFileMenu:
nMenuMode = nFileMenu;
break;
}
// write key pressed and time on player
StoreAction(oPC, nAction);
break;
case nColorMenu:
nMenuMode = nMainMenu;
if ((nAction>=1) && (nAction<=20))
{
// The user has selected a color. Lets get the color tag.
sInsert = GetColorTag(nAction-1);
}
else if (nAction==21)
{
// The user has selected the close color tag.
sInsert = "</c>";
}
else
{
// The user has probably selected 'Back to main menu'
sInsert = "";
}
if (sInsert!="")
{
if (IsBlockMarked(nCursor, nBlock) && (nAction!=21))
{
// If a block is marked (and a color tag is choosen) we add
// a close color tag behind the block and the color tag in
// front of the block. That will make sure that only the
// marked block gets colored.
sText = InsertText(sText, _max(nCursor, nBlock), "</c>", nMaxLength);
sText = InsertText(sText, _min(nCursor, nBlock), sInsert, nMaxLength);
if (nBlock<nCursor)
{
// make sure the (visible) cursor position does not
// change (6+4=10)
nCursor+=10;
}
}
else
{
// No block is marked, we only insert the desired tag at
// cursor position.
sText = InsertText(sText, nCursor, sInsert, nMaxLength);
// Move the cursor behind the tag.
nCursor = IncCursor(sText, nCursor);
}
nBlock = -1;
}
break;
case nFileMenu:
nMenuMode = nMainMenu;
if ((nAction>=1) && (nAction<=nNumberOfLoadSaveSlots))
{
SaveTextToSlot(oPC, nAction, sText);
}
else if ((nAction>nNumberOfLoadSaveSlots) && (nAction<2*nNumberOfLoadSaveSlots))
{
sText = LoadTextFromSlot(oPC, nAction-nNumberOfLoadSaveSlots,
nMaxLength, (bSingleLine ? 1 : 0));
nBlock = -1;
nCursor = GetStringLength(sText);
}
break;
}
MK_DELIMITER_Initialize();
switch (nMenuMode)
{
case nMainMenu:
// If the block operations are disabled the appropriate dialog options
// are disabled as well.
// Also if the clipboard is empty the 'Shift Insert' option is
// disabled.
MK_GenericDialog_SetCondition(nKeyShiftPos1, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyShiftCursorLeft, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyShiftCursorRight, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyShiftEnd, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyShiftInsert, (sClipboard!="") && (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyShiftDelete, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyCtrlInsert, (!bDisableBlock));
MK_GenericDialog_SetCondition(nKeyReturn, !bSingleLine);
// If colors are disabled the color menu is disabled.
MK_GenericDialog_SetCondition(nKeyColorMenu, !bDisableColors);
MK_GenericDialog_SetCondition(nKeyFileMenu, !bDisableLoadSave);
MK_GenericDialog_SetCondition(GetLocalInt(oPC, g_varEditorOK), TRUE);
MK_GenericDialog_SetCondition(GetLocalInt(oPC, g_varEditorCancel), TRUE);
break;
case nColorMenu:
// Create the color menu.
SetColorMenuStrings();
break;
case nFileMenu:
// Create the file menu.
SetFileMenuStrings(oPC);
break;
}
// Generate the editor screen.
CreateDisplay(oPC, sText, nCursor, nBlock);
// Store the editor variables on the player.
SetLocalString(oPC, g_varEditorBuffer, sText);
SetLocalString(oPC, g_varEditorClipboard, sClipboard);
SetLocalInt(oPC, g_varEditorCursor, nCursor);
SetLocalInt(oPC, g_varEditorBlock, nBlock);
SetLocalInt(oPC, g_varEditorMenuMode, nMenuMode);
return TRUE;
}
int _min(int a, int b)
{
if (a==-1) return b;
if (b==-1) return a;
if (a<b) return a;
return b;
}
int _max(int a, int b)
{
if (a==-1) return b;
if (b==-1) return a;
if (a<b) return b;
return a;
}
string CopyBlock(string sText, int nStart, int nEnd)
{
/* MK_DEBUG_TRACE("CopyBlock: "+
"sText="+sText+", "+
"nStart="+IntToString(nStart)+", "+
"nEnd="+IntToString(nEnd));
*/
int nStart0 = _min(nStart, nEnd);
int nEnd0 = _max(nStart, nEnd);
int nLength = GetStringLength(sText);
string sCopy = GetSubString(sText, nStart0, nEnd0-nStart0);
/* MK_DEBUG_TRACE("CopyBlock: "+
"sCopy="+sCopy);
*/
return sCopy;
}
string DeleteBlock(string sText, int nStart, int nEnd)
{
/* MK_DEBUG_TRACE("DeleteBlock: "+
"sText="+sText+", "+
"nStart="+IntToString(nStart)+", "+
"nEnd="+IntToString(nEnd));
*/
int nStart0 = _min(nStart, nEnd);
int nEnd0 = _max(nStart, nEnd);
int nLength = GetStringLength(sText);
string sLeft = GetStringLeft(sText,nStart0);
string sRight = GetStringRight(sText,nLength-nEnd0);
/* MK_DEBUG_TRACE("DeleteBlock: "+
"sLeft="+sLeft+", "+
"sRight="+sRight);
*/
return sLeft+sRight;
}
string InsertText(string sText, int nPos, string sInsert, int nMaxLength)
{
/* MK_DEBUG_TRACE("InsertText: "+
"sText="+sText+", "+
"nPos="+IntToString(nPos)+", "+
"sInsert="+sInsert);
*/
int nLength = GetStringLength(sText);
string sLeft = GetStringLeft(sText,nPos);
string sRight = GetStringRight(sText,nLength-nPos);
if (nMaxLength>0)
{
nLength = MK_GetStringLength(sLeft, TRUE)
+ MK_GetStringLength(sRight, TRUE);
if ((nLength + MK_GetStringLength(sInsert, TRUE)) > nMaxLength)
{
sInsert = MK_GetStringLeft(sInsert, nMaxLength-nLength, TRUE);
}
}
/* MK_DEBUG_TRACE("InsertText: "+
"sLeft="+sLeft+", "+
"sRight="+sRight);
*/
return sLeft+sInsert+sRight;
}
string AddColorTag(string sText, string sColorTag)
{
return sColorTag+sText+sCloseTag;
}
void CreateDisplay(object oPC, string sText, int nCursor, int nBlock)
{
/* MK_DEBUG_TRACE("CreateDisplay(1): "+
"sText="+sText+", "+
"nCursor="+IntToString(nCursor)+", "+
"nBlock="+IntToString(nBlock));
*/
int nLength = GetStringLength(sText);
string s1 = IntToString(nCursor+1);
string s2 = IntToString(nLength);
string s3 = "";
string sBlockColorTagQ;
if (IsBlockMarked(nCursor, nBlock))
{
/*
The following would work great (well, sort of) if there were only
one font. Unfortunately there's the 'normal' font and the high resolution
font and usually characters in the normal font have a smaller size and
there's no way to get the used font size in nwscript.
// We want the text 'Block' to be right aligned.
// So lets calculate the required number of spaces.
// The '---...---' line is 258 pixel
// The 'Cursor pos: ' is 79 pixel
// The '/' is 6 pixel
// The 'Block' is 35 pixel
// A ' ' is 4 pixel
int nPixelToFill = 258 - (79 + MK_GetStringSize(s1) + 6
+ MK_GetStringSize(s2) + 35);
int nNumberOfSpaces = nPixelToFill / 4;
s3 = GetStringLeft(sEmptyLine, nNumberOfSpaces) + "Block";
So let's drop the idea of having right aligned text in the status line.
*/
s3 = "Block On";
sBlockColorTagQ = sBlockColorTag;
}
else
{
s3 = "Block Off";
sBlockColorTagQ = sText2ColorTag;
}
int nSpaces = (100 - (MK_GetStringSize(s1) + MK_GetStringSize(s2))) / 4;
s3 = GetStringLeft(sEmptyLine,nSpaces) + s3;
int nMin = _min(nCursor, nBlock);
int nMax = _max(nCursor, nBlock);
string sLeft = GetStringLeft(sText, nMin);
string sRight = GetStringRight(sText, nLength - nMax);
string sMid;
if ((nBlock==-1) || (nBlock==nCursor))
{
sMid = AddColorTag(sCursor, sCursorColorTag);
}
else
{
sMid = AddColorTag(GetSubString(sText, nMin, nMax-nMin), sBlockColorTag);
}
/* MK_DEBUG_TRACE("CreateDisplay(2): "+
"sLeft="+sLeft+", "+
"sMid="+sMid+", "+
"sRight="+sRight);
*/
string s4 = GetLocalString(oPC, g_varEditorHeadLine);
if (s4=="")
{
s4 = sEditorHeadLine;
}
SetCustomToken(19995, s4);
SetCustomToken(19996, AddColorTag(s3, sBlockColorTagQ));
SetCustomToken(19997, AddColorTag(s2, sCursorColorTag));
SetCustomToken(19998, AddColorTag(s1, sCursorColorTag));
SetCustomToken(19999, sLeft+sMid+sRight);
}
int IsBlockMarked(int nCursor, int nBlock)
{
if ((nBlock==-1) || (nCursor==nBlock))
{
return FALSE;
}
return TRUE;
}
void InitCustomTokens()
{
SetCustomToken(19992, sLineOnScreen);
SetCustomToken(19991, sColoredColor);
SetCustomToken(19990, sCloseTag);
SetCustomToken(19989, sExitColorTag); // color of 'OK'
SetCustomToken(19988, sText1ColorTag); // color text
SetCustomToken(19987, sText2ColorTag); // color head line, foot line
SetCustomToken(19986, sColorOffColorTag);// color of 'Color Off'
SetCustomToken(19985, sCancelColorTag); // color of 'Cancel'
SetCustomToken(19984, sKeyColorTag); // color keys
SetCustomToken(19983, sInsertColorTag); // color insert
SetCustomToken(19982, sBackToMainMenuColor); // color 'back to main menu
SetCustomToken(19981, sHelpColorTag); // color 'Help'
SetCustomToken(19980, sLoadSaveColorTag);
}
int IncCursor(string sText, int nCursor, int nDelta)
{
int nLen = GetStringLength(sText);
while ((nCursor<nLen) && (nDelta>0))
{
if (MK_IsColorTag(sText,nCursor))
{
nCursor+=6;
}
else if (MK_IsCloseTag(sText,nCursor))
{
nCursor+=4;
}
else if (nCursor<nLen)
{
nCursor++;
}
nDelta--;
}
return nCursor;
}
int DecCursor(string sText, int nCursor, int nDelta)
{
while ((nCursor>0) && (nDelta>0))
{
if ((nCursor>5) && (MK_IsColorTag(sText,nCursor-6)))
{
nCursor-=6;
}
else if ((nCursor>3) && (MK_IsCloseTag(sText,nCursor-4)))
{
nCursor-=4;
}
else if (nCursor>0)
{
nCursor--;
}
nDelta--;
}
return nCursor;
}
int GetColor2DAMode()
{
object oModule = GetModule();
if (!GetIsObjectValid(oModule)) return 2;
int nColor2DAMode = GetLocalInt(oModule, g_varEditorColor2DA);
if (nColor2DAMode==0)
{
if (Get2DAString(sColor2DA, sColor2DAName, 0)!="")
{
nColor2DAMode=1;
}
else
{
nColor2DAMode=2;
}
SetLocalInt(oModule, g_varEditorColor2DA, nColor2DAMode);
}
return nColor2DAMode;
}
string GetColorName(int iColor)
{
string sColor;
if (GetColor2DAMode()==1)
{
sColor = Get2DAString(sColor2DA, sColor2DAName, iColor);
}
else
{
switch (iColor)
{
case 0: sColor = sColorNameRed; break;
case 1: sColor = sColorNameGreen; break;
case 2: sColor = sColorNameBlue; break;
case 3: sColor = sColorNameCyan; break;
case 4: sColor = sColorNameMagenta; break;
case 5: sColor = sColorNameYellow; break;
default: sColor = "";
}
}
return sColor;
}
string GetColorTag(int iColor)
{
string sTag;
if (GetColor2DAMode()==1)
{
sTag = Get2DAString(sColor2DA, sColor2DATag, iColor);
}
else
{
switch (iColor)
{
case 0: sTag = sColorTagRed; break;
case 1: sTag = sColorTagGreen; break;
case 2: sTag = sColorTagBlue; break;
case 3: sTag = sColorTagCyan; break;
case 4: sTag = sColorTagMagenta; break;
case 5: sTag = sColorTagYellow; break;
default: sTag = "";
}
}
return sTag;
}
void SetColorMenuStrings()
{
int iColor=0;
int bOk = TRUE;
string sColor, sTag;
string sLine;
while (bOk)
{
bOk = FALSE;
sColor = GetColorName(iColor);
if (sColor!="")
{
sTag = GetColorTag(iColor);
if (MK_IsColorTag(sTag))
{
sLine = sTag+sColor+"</c>";
SetCustomToken(19951+iColor, sLine);
MK_GenericDialog_SetCondition(iColor+1, TRUE);
bOk = TRUE;
iColor++;
}
}
else
{
}
}
while (iColor<20)
{
MK_GenericDialog_SetCondition(iColor+1, FALSE);
iColor++;
}
MK_GenericDialog_SetCondition(21, TRUE); // Color off
}
string GetFileSlotVarName(int nSlot)
{
return g_varEditorLoadSaveSlots +
MK_IntToString(nSlot, 2, "0");
}
string LoadTextFromSlot(object oObject, int nSlot, int nMaxLength, int nLineFeedMode)
{
string sSlotVarName = GetFileSlotVarName(nSlot);
string sText = GetLocalString(oObject, sSlotVarName);
if ((nMaxLength>0) && (MK_GetStringLength(sText, TRUE)>nMaxLength))
{
sText = MK_GetStringLeft(sText, nMaxLength, TRUE);
}
switch (nLineFeedMode)
{
case 0: // ignore
break;
case 1: // cut
{
int nNewLinePos = FindSubString(sText, "\n");
if (nNewLinePos!=-1)
{
sText = GetStringLeft(sText, nNewLinePos);
}
}
break;
case 2: // remove
sText = MK_RemoveFromString(sText, "\n");
break;
}
return sText;
}
void SaveTextToSlot(object oObject, int nSlot, string sText)
{
string sSlotVarName = GetFileSlotVarName(nSlot);
SetLocalString(oObject, sSlotVarName, sText);
}
string CreateFileMenuText(object oObject, int bSave, int nSlot)
{
string sLine="";
string sText = LoadTextFromSlot(oObject, nSlot, -1, 2);
if ((!bSave) && (sText==""))
{
// we don't want to load empty text;
return sLine;
}
// if the text is too long we display only the first characters
if (MK_GetStringLength(sText,TRUE)>nMaxTextDisplayLength)
{
sText = MK_GetStringLeft(sText, nMaxTextDisplayLength-2, TRUE) + "...";
}
if (sText=="")
{
sText = "empty";
}
else
{
sText = "'"+sText+"'";
}
sLine = (bSave ? sSaveToSlotColorTag + "Save to" :
sLoadFromSlotColorTag + "Load from") +
" slot " + MK_IntToString(nSlot, 2, "0") + sCloseTag +
" (" + sText + ")";
return sLine;
}
void SetFileMenuStrings(object oObject)
{
int nStartToken = 19951;
int i=0;
string sLine;
while (++i<=2*nNumberOfLoadSaveSlots)
{
sLine = CreateFileMenuText(oObject,
i<=nNumberOfLoadSaveSlots,
((i-1) % nNumberOfLoadSaveSlots) +1);
SetCustomToken(nStartToken+i-1, sLine);
MK_GenericDialog_SetCondition(i,sLine!="");
}
do
{
MK_GenericDialog_SetCondition(i, FALSE);
}
while (++i<=21);
}
string GetPCChatMessageEx(object oPC, int bUsePlayerChatEvent)
{
string sMessage;
if (bUsePlayerChatEvent)
{
sMessage = GetLocalString(oPC, g_varEditorChatMessageString);
}
else
{
sMessage = GetPCChatMessage();
}
return sMessage;
}
void IncLocalInt(object oObject, string sVarName, int n)
{
if (!GetIsObjectValid(oObject)) return;
int nValue = GetLocalInt(oObject, sVarName);
nValue+=n;
SetLocalInt(oObject, sVarName, nValue);
}
struct mk_lastaction
{
int nAction;
float fTimeStamp;
};
// stores nAction and the current time on the oObject
void StoreAction(object oObject, int nAction)
{
SetLocalInt(oObject, g_varEditorLastAction, nAction);
mk_writeTimeStampToObject(oObject, g_varEditorTimeStamp);
}
// reads nAction and time stamp from oObject
struct mk_lastAction GetLastAction(object oObject)
{
struct mk_lastAction lastAction;
lastAction.nAction = GetLocalInt(oObject, g_varEditorLastAction);
lastAction.fTimeStamp = mk_getTimeSinceTimeStamp(oObject, g_varEditorTimeStamp);
return lastAction;
}
int CalculateCursorSpeed(object oObject, int nAction)
{
int nCursorSpeed=1;
struct mk_lastAction lastAction = GetLastAction(oObject);
int nCursorSpeedMode;
if (nAction==lastAction.nAction)
{
nCursorSpeedMode = GetLocalInt(oObject, g_varEditorCursorSpeedMode);
// Time passed in milliseconds
float fTimeSpan = lastAction.fTimeStamp * 2.0f * 60.0f * 1000.0f;
struct mk_datetime dateTimeSpan =
mk_timeStampToDateTimeSpan(lastAction.fTimeStamp);
string sOutput = mk_formatDateTimeSpan(dateTimeSpan);
// MK_DEBUG_TRACE("Delta="+sOutput+" ("+FloatToString(lastAction.fTimeStamp)+") ,"
// +IntToString(FloatToInt(fTimeSpan))+" milliseconds.");
if (fTimeSpan < fSpeedUpCursorMovementTime)
{
nCursorSpeedMode++;
}
else if (fTimeSpan < 2.0 * fSpeedUpCursorMovementTime)
{
}
else if (fTimeSpan < 3.0 * fSpeedUpCursorMovementTime)
{
nCursorSpeedMode--;
}
else
{
nCursorSpeedMode=1;
}
if (nCursorSpeedMode< 1) nCursorSpeedMode= 1;
if (nCursorSpeedMode>10) nCursorSpeedMode=10;
}
else
{
nCursorSpeedMode = 1;
}
SetLocalInt(oObject, g_varEditorCursorSpeedMode, nCursorSpeedMode);
switch (nCursorSpeedMode)
{
case 1:
case 2:
nCursorSpeed=1;
break;
case 3:
case 4:
nCursorSpeed=2;
break;
case 5:
case 6:
nCursorSpeed=3;
break;
case 7:
case 8:
nCursorSpeed=4;
break;
case 9:
case 10:
nCursorSpeed=5;
break;
}
/*
MK_DEBUG_TRACE(
"CursorSpeedMode=" + IntToString(nCursorSpeedMode)+", "+
"CursorSpeed=" + IntToString(nCursorSpeed));
*/
return nCursorSpeed;
}
/*
void main()
{
}
/**/