Cleaned up the mess, at this time, only viable data get synced (_work directory for Gothic-data, miranda for mdc-scripts. Need to symlink files to a working directory.
233 lines
9 KiB
D
233 lines
9 KiB
D
// a maximum of 11 (1 active + 10 waiting in queue) achievements can be unlocked at once
|
|
// should be enough, otherwise I'll increase the amount
|
|
var int SPINE_ACHIEVEMENTSQUEUE[10];
|
|
var int Spine_AchievementView;
|
|
var int Spine_AchievementImageView;
|
|
|
|
var int Spine_UnlockAchievementFunc;
|
|
var int Spine_IsAchievementUnlockedFunc;
|
|
var int Spine_UpdateAchievementProgressFunc;
|
|
var int Spine_GetAchievementProgressFunc;
|
|
var int Spine_GetAchievementMaxProgressFunc;
|
|
var int Spine_GetShowAchievementsFunc;
|
|
|
|
// return TRUE or FALSE whether the achievement for the given id is already unlocked or not
|
|
func int Spine_IsAchievementUnlocked(var int identifier) {
|
|
if (Spine_Initialized && Spine_IsAchievementUnlockedFunc) {
|
|
CALL_IntParam(identifier);
|
|
CALL__cdecl(Spine_IsAchievementUnlockedFunc);
|
|
return CALL_RetValAsInt();
|
|
};
|
|
return TRUE;
|
|
};
|
|
|
|
// private, don't call from outside
|
|
func void Spine_ShowAchievementView(var int identifier) {
|
|
var zCPar_Symbol sym; sym = _^(MEMINT_SwitchG1G2(MEM_GetSymbol("_STR_FONT_ONSCREEN"), // Font constant G1
|
|
MEM_GetSymbol("FONT_SCREENSMALL"))); // Font constant G2
|
|
var string Spine_Font; Spine_Font = MEM_ReadString(sym.content);
|
|
var int startPosX;
|
|
var int startPosY;
|
|
var zCView screen; screen = _^(MEM_Game._zCSession_viewport);
|
|
if (SPINE_ACHIEVEMENTORIENTATION == SPINE_TOPLEFT) {
|
|
startPosX = 0;
|
|
startPosY = 0;
|
|
} else if (SPINE_ACHIEVEMENTORIENTATION == SPINE_TOPRIGHT) {
|
|
startPosX = screen.psizex - SPINE_ACHIEVEMENT_WIDTH;
|
|
startPosY = 0;
|
|
} else if (SPINE_ACHIEVEMENTORIENTATION == SPINE_BOTTOMLEFT) {
|
|
startPosX = 0;
|
|
startPosY = screen.psizey - SPINE_ACHIEVEMENT_HEIGHT;
|
|
} else if (SPINE_ACHIEVEMENTORIENTATION == SPINE_BOTTOMRIGHT) {
|
|
startPosX = screen.psizex - SPINE_ACHIEVEMENT_WIDTH;
|
|
startPosY = screen.psizey - SPINE_ACHIEVEMENT_HEIGHT;
|
|
};
|
|
Spine_AchievementView = View_CreatePxl(startPosX, startPosY, startPosX + SPINE_ACHIEVEMENT_WIDTH, startPosY + SPINE_ACHIEVEMENT_HEIGHT);
|
|
View_SetTexture(Spine_AchievementView, "ACHIEVEMENT_BACKGROUND.TGA");
|
|
View_Open(Spine_AchievementView);
|
|
|
|
var int imageStartPosX;
|
|
var int imageStartPosY;
|
|
var int imageOffset;
|
|
imageOffset = (SPINE_ACHIEVEMENT_HEIGHT - SPINE_ACHIEVEMENT_IMAGE_HEIGHT) / 2;
|
|
imageStartPosX = startPosX + imageOffset;
|
|
imageStartPosY = startPosY + imageOffset;
|
|
Spine_AchievementImageView = View_CreatePxl(imageStartPosX, imageStartPosY, imageStartPosX + SPINE_ACHIEVEMENT_IMAGE_WIDTH, imageStartPosY + SPINE_ACHIEVEMENT_IMAGE_HEIGHT);
|
|
var string achievementTexture;
|
|
achievementTexture = MEM_ReadStatStringArr(SPINE_ACHIEVEMENT_TEXTURES, identifier);
|
|
View_SetTexture(Spine_AchievementImageView, achievementTexture);
|
|
View_Open(Spine_AchievementImageView);
|
|
|
|
var string achievementName;
|
|
achievementName = MEM_ReadStatStringArr(SPINE_ACHIEVEMENT_NAMES, identifier);
|
|
var int textLength; textLength = Print_GetStringWidth(achievementName, Spine_Font);
|
|
if (textLength <= SPINE_ACHIEVEMENT_WIDTH - (SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 3)) {
|
|
View_AddText(Spine_AchievementView, Print_ToVirtual(SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 2, SPINE_ACHIEVEMENT_WIDTH), Print_ToVirtual(imageOffset, SPINE_ACHIEVEMENT_HEIGHT), achievementName, Spine_Font);
|
|
} else { // Text is too long for the field
|
|
var int height; height = 0;
|
|
var int splitCount; splitCount = STR_SplitCount(achievementName, " ");
|
|
var int i; i = 0;
|
|
var string currentLine; currentLine = "";
|
|
var int pos; pos = MEM_StackPos.position;
|
|
if (i < splitCount) {
|
|
var string currentLineTest;
|
|
if (STR_Len(currentLine) > 0) {
|
|
currentLine = ConcatStrings(currentLine, " ");
|
|
};
|
|
currentLineTest = ConcatStrings(currentLine, STR_Split(achievementName, " ", i));
|
|
textLength = Print_GetStringWidth(currentLineTest, Spine_Font);
|
|
if (textLength > SPINE_ACHIEVEMENT_WIDTH - (SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 3)) {
|
|
if (STR_Len(currentLine) == 0) {
|
|
View_AddText(Spine_AchievementView, Print_ToVirtual(SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 2, SPINE_ACHIEVEMENT_WIDTH), Print_ToVirtual(imageOffset + height, SPINE_ACHIEVEMENT_HEIGHT), currentLineTest, Spine_Font);
|
|
currentLine = "";
|
|
currentLineTest = "";
|
|
} else {
|
|
View_AddText(Spine_AchievementView, Print_ToVirtual(SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 2, SPINE_ACHIEVEMENT_WIDTH), Print_ToVirtual(imageOffset + height, SPINE_ACHIEVEMENT_HEIGHT), currentLine, Spine_Font);
|
|
currentLine = STR_Split(achievementName, " ", i);
|
|
currentLineTest = "";
|
|
};
|
|
height += Print_GetFontHeight(Spine_Font);
|
|
} else {
|
|
currentLine = currentLineTest;
|
|
};
|
|
i += 1;
|
|
MEM_StackPos.position = pos;
|
|
};
|
|
if (STR_Len(currentLine) > 0) {
|
|
View_AddText(Spine_AchievementView, Print_ToVirtual(SPINE_ACHIEVEMENT_IMAGE_WIDTH + imageOffset * 2, SPINE_ACHIEVEMENT_WIDTH), Print_ToVirtual(imageOffset + height, SPINE_ACHIEVEMENT_HEIGHT), currentLine, Spine_Font);
|
|
};
|
|
};
|
|
|
|
FF_Remove(Spine_RemoveAchievementView);
|
|
FF_ApplyOnceExt(Spine_RemoveAchievementView, SPINE_ACHIEVEMENT_DISPLAY_TIME, 1);
|
|
};
|
|
|
|
// unlocks achievement for this mod for given id
|
|
// contact Bonne to get your achievements on the server
|
|
// will also automatically create a view informing about unlocking the achievement
|
|
// unless it is disabled via setting SPINE_SHOWACHIEVEMENTS = FALSE
|
|
// place on the screen can be changed setting SPINE_ACHIEVEMENTORIENTATION
|
|
func void Spine_UnlockAchievement(var int identifier) {
|
|
if (Spine_Initialized && Spine_UnlockAchievementFunc) {
|
|
if (!Spine_IsAchievementUnlocked(identifier)) {
|
|
CALL_IntParam(identifier);
|
|
CALL__cdecl(Spine_UnlockAchievementFunc);
|
|
|
|
if (Spine_AchievementView == 0) {
|
|
Spine_ShowAchievementView(identifier);
|
|
} else {
|
|
var int i; i = 0;
|
|
var int pos; pos = MEM_StackPos.position;
|
|
|
|
var int hndl; hndl = MEM_ReadStatArr(SPINE_ACHIEVEMENTSQUEUE, i);
|
|
|
|
if (hndl == -1) {
|
|
MEM_WriteStatArr(SPINE_ACHIEVEMENTSQUEUE, i, identifier);
|
|
} else {
|
|
i += 1;
|
|
if (i < 10) {
|
|
MEM_StackPos.position = pos;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// updates achievement progress
|
|
// in case maximum achievement progress is reached, the achievement is displayed as unlocked automatically
|
|
func void Spine_UpdateAchievementProgress(var int identifier, var int progress) {
|
|
if (Spine_Initialized && Spine_UpdateAchievementProgressFunc) {
|
|
if (!Spine_IsAchievementUnlocked(identifier)) {
|
|
CALL_IntParam(progress);
|
|
CALL_IntParam(identifier);
|
|
CALL__cdecl(Spine_UpdateAchievementProgressFunc);
|
|
var int ret; ret = CALL_RetValAsInt();
|
|
|
|
if (Spine_GetTestMode()) {
|
|
var string maxProgressString; maxProgressString = MEM_ReadStatStringArr(SPINE_ACHIEVEMENT_PROGRESS, identifier);
|
|
var int maxProgress; maxProgress = STR_ToInt(maxProgressString);
|
|
if (maxProgress <= progress) {
|
|
ret = TRUE;
|
|
};
|
|
};
|
|
|
|
if (ret) {
|
|
if (Spine_AchievementView == 0) {
|
|
Spine_ShowAchievementView(identifier);
|
|
} else {
|
|
var int i; i = 0;
|
|
var int pos; pos = MEM_StackPos.position;
|
|
|
|
var int hndl; hndl = MEM_ReadStatArr(SPINE_ACHIEVEMENTSQUEUE, i);
|
|
|
|
if (hndl == -1) {
|
|
MEM_WriteStatArr(SPINE_ACHIEVEMENTSQUEUE, i, identifier);
|
|
} else {
|
|
i += 1;
|
|
if (i < 10) {
|
|
MEM_StackPos.position = pos;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// returns the current progress of an achievement or 0 in case it is an achievement without progress
|
|
func int Spine_GetAchievementProgress(var int identifier) {
|
|
if (Spine_Initialized && Spine_GetAchievementProgressFunc) {
|
|
CALL_IntParam(identifier);
|
|
CALL__cdecl(Spine_GetAchievementProgressFunc);
|
|
return CALL_RetValAsInt();
|
|
};
|
|
return FALSE;
|
|
};
|
|
|
|
// returns the maximum progress to reach of an achievement or 0 in case it is an achievement without progress
|
|
func int Spine_GetAchievementMaxProgress(var int identifier) {
|
|
if (Spine_Initialized && Spine_GetAchievementMaxProgressFunc) {
|
|
if (Spine_GetTestMode()) {
|
|
var string maxProgressString; maxProgressString = MEM_ReadStatStringArr(SPINE_ACHIEVEMENT_PROGRESS, identifier);
|
|
var int maxProgress; maxProgress = STR_ToInt(maxProgressString);
|
|
return maxProgress;
|
|
} else {
|
|
CALL_IntParam(identifier);
|
|
CALL__cdecl(Spine_GetAchievementMaxProgressFunc);
|
|
return CALL_RetValAsInt();
|
|
};
|
|
};
|
|
return FALSE;
|
|
};
|
|
|
|
// private, don't call from outside
|
|
func void Spine_RemoveAchievementView() {
|
|
if (Hlp_IsValidHandle(Spine_AchievementView)) {
|
|
View_Delete(Spine_AchievementView);
|
|
Spine_AchievementView = 0;
|
|
};
|
|
if (Hlp_IsValidHandle(Spine_AchievementImageView)) {
|
|
View_Delete(Spine_AchievementImageView);
|
|
Spine_AchievementImageView = 0;
|
|
};
|
|
FF_Remove(Spine_ShowAchievementView);
|
|
if (SPINE_ACHIEVEMENTSQUEUE[0] != -1) {
|
|
var int identifier;
|
|
identifier = SPINE_ACHIEVEMENTSQUEUE[0];
|
|
var int i; i = 0;
|
|
var int pos; pos = MEM_StackPos.position;
|
|
|
|
var int hndl; hndl = MEM_ReadStatArr(SPINE_ACHIEVEMENTSQUEUE, i);
|
|
|
|
if (hndl != -1) {
|
|
MEM_WriteStatArr(SPINE_ACHIEVEMENTSQUEUE, i, MEM_ReadStatArr(SPINE_ACHIEVEMENTSQUEUE, i + 1));
|
|
i += 1;
|
|
if (i < 9) {
|
|
MEM_StackPos.position = pos;
|
|
};
|
|
};
|
|
MEM_WriteStatArr(SPINE_ACHIEVEMENTSQUEUE, i, -1);
|
|
FF_ApplyOnceExtData(Spine_ShowAchievementView, 0, 1, identifier);
|
|
};
|
|
};
|