.Rise 18 Posted March 5, 2018 Share Posted March 5, 2018 Hello, I have created C++ code for adding more than 1 point of stat. I have made it only in C++. Python part is not included (you have to code it by yourself). Description: When you use specific command (/multiplestat arg1 arg2) your status (body) points will increase by value of arg2. It is bug fixxed (no known bugs). When you try to add more than is allowed by MAX_STAT, stats are increased to limit and left points will not be decreased. Usage: /multiplestat <st/dx/ht/iq> <amount> => st = strenght | dx = dexterity | ht = vitality | iq = intelligence Installation: service.h: Spoiler Add into defines: #define ENABLE_BULK_STATS cmd.cpp: Spoiler Find: "ACMD(do_stat);" and add under: #ifdef ENABLE_BULK_STATS ACMD(do_multiplestat); #endif Add in "command_info cmd_info[] =": #ifdef ENABLE_BULK_STATS { "multiplestat", do_multiplestat, 0, POS_DEAD, GM_PLAYER }, #endif cmd_general.cpp: Spoiler Find "ACMD(do_stat)" and add under the function: #ifdef ENABLE_BULK_STATS ACMD(do_multiplestat) { char arg1[256]; char arg2[256]; int amount; int toreturn; int idx; int aamount; two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)); if (!*arg1 || !*arg2) return; amount = atoi(arg2); idx = 0; toreturn = 0; if (ch->IsPolymorphed()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다.")); return; } if (ch->GetPoint(POINT_STAT) <= 0) { int errorcode = 1; ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d<multiplestat_error>."), errorcode); return; } if (!strcmp(arg1, "st")) idx = POINT_ST; else if (!strcmp(arg1, "dx")) idx = POINT_DX; else if (!strcmp(arg1, "ht")) idx = POINT_HT; else if (!strcmp(arg1, "iq")) idx = POINT_IQ; else if (amount > ch->GetPoint(POINT_STAT)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<no_available_status_points>.")); return; } if (ch->GetRealPoint(idx) + amount >= MAX_STAT) { aamount = ch->GetRealPoint(idx) + amount; toreturn = aamount - MAX_STAT; if (ch->GetRealPoint(idx) - amount <= 0) ch->SetRealPoint(idx, ch->GetRealPoint(idx) + amount - toreturn); ch->SetPoint(idx, ch->GetPoint(idx) + amount - toreturn); ch->ComputePoints(); ch->PointChange(idx, 0); if (idx == POINT_IQ) { ch->PointChange(POINT_MAX_HP, 0); } else if (idx == POINT_HT) { ch->PointChange(POINT_MAX_SP, 0); } ch->PointChange(POINT_STAT, -(amount) + toreturn); ch->ComputePoints(); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d<limit_status_points>."), MAX_STAT); return; } ch->SetRealPoint(idx, ch->GetRealPoint(idx) + amount); ch->SetPoint(idx, ch->GetPoint(idx) + amount); ch->ComputePoints(); ch->PointChange(idx, 0); if (idx == POINT_IQ) { ch->PointChange(POINT_MAX_HP, 0); } else if (idx == POINT_HT) { ch->PointChange(POINT_MAX_SP, 0); } ch->PointChange(POINT_STAT, -(amount)); ch->ComputePoints(); } #endif locale_string.txt: Spoiler "<no_available_status_points>."; "You do not have enough available status points."; "%d<limit_status_points>."; "You can not go over limit. Limit is %d points."; "%d<multiplestat_error>."; "There is unexpected error. Contact administrator (#%d)"; I hope this easy code will help someone. Regards. (sorry for my english) 1 If I helped you, do not forget to press "Thanks" button! Link to comment Share on other sites More sharing options...
Management Karbust 4927 Posted March 5, 2018 Management Share Posted March 5, 2018 Are you trying to create a command like: /con+ <arg1> /int <arg1> /str <arg1> /dex <arg1> This already gives the points you want to add, example: /con+ 50 This will "move" 50 of you available points into VIT Correct me if didn't understand your topic... Link to comment Share on other sites More sharing options...
.Rise 18 Posted March 5, 2018 Author Share Posted March 5, 2018 1 minute ago, charparodar said: Are you trying to create a command like: /con+ <arg1> /int <arg1> /str <arg1> /dex <arg1> This already gives the points you want to add, example: /con+ 50 This will "move" 50 of you available points into VIT Correct me if didn't understand your topic... Oh.. I didnt know that there is those commands.. But I hope it is not included in all SF and it will help somebody. If I helped you, do not forget to press "Thanks" button! Link to comment Share on other sites More sharing options...
Management Karbust 4927 Posted March 5, 2018 Management Share Posted March 5, 2018 1 minute ago, .Rise said: Oh.. I didnt know that there is those commands.. But I hope it is not included in all SF and it will help somebody. It's included in the source... I already used it on 2089M... Link to comment Share on other sites More sharing options...
.Rise 18 Posted March 5, 2018 Author Share Posted March 5, 2018 2 minutes ago, charparodar said: It's included in the source... I already used it on 2089M... Okay.. I did not now. EDIT: I tested it now and it ignores stats limits.. So not usable for players.. If I helped you, do not forget to press "Thanks" button! Link to comment Share on other sites More sharing options...
Management Karbust 4927 Posted March 5, 2018 Management Share Posted March 5, 2018 Just now, .Rise said: Okay.. I did not now. EDIT: I have tested it now and it ignores stats limits.. So not usable for players.. What do you mean stats limits? I've used it on a lot of servers, including my own, and it respects the limits of stats... Example, if the server limits 100 it doesn't go up that, in fact it doesn't even used the points until you try a lower value that fits the limit... Link to comment Share on other sites More sharing options...
.Rise 18 Posted March 5, 2018 Author Share Posted March 5, 2018 (edited) 1 minute ago, charparodar said: What do you mean stats limits? I've used it on a lot of servers, including my own, and it respects the limits of stats... Example, if the server limits 100 it doesn't go up that, in fact it doesn't even used the points until you try a lower value that fits the limit... I have 100 points limit but I can use /con+ 363 and it goes over the limit Edited August 24, 2022 by Metin2 Dev Core X - External 2 Internal If I helped you, do not forget to press "Thanks" button! Link to comment Share on other sites More sharing options...
Management Karbust 4927 Posted March 5, 2018 Management Share Posted March 5, 2018 ACMD(do_stat_plus_amount) { char szPoint[256]; one_argument(argument, szPoint, sizeof(szPoint)); if (*szPoint == '\0') return; if (ch->IsPolymorphed()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다.")); return; } int nRemainPoint = ch->GetPoint(POINT_STAT); if (nRemainPoint <= 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 없습니다.")); return; } int nPoint = 0; str_to_number(nPoint, szPoint); if (nRemainPoint < nPoint) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 적습니다.")); return; } if (nPoint < 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("값을 잘못 입력하였습니다.")); return; } switch (subcmd) { case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > 90) { nPoint = 90 - ch->GetPoint(POINT_HT); } break; case POINT_IQ : // 지능 if (nPoint + ch->GetPoint(POINT_IQ) > 90) { nPoint = 90 - ch->GetPoint(POINT_IQ); } break; case POINT_ST : // 근력 if (nPoint + ch->GetPoint(POINT_ST) > 90) { nPoint = 90 - ch->GetPoint(POINT_ST); } break; case POINT_DX : // 민첩 if (nPoint + ch->GetPoint(POINT_DX) > 90) { nPoint = 90 - ch->GetPoint(POINT_DX); } break; default : ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("명령어의 서브 커맨드가 잘못 되었습니다.")); return; break; } if (nPoint != 0) { ch->SetRealPoint(subcmd, ch->GetRealPoint(subcmd) + nPoint); ch->SetPoint(subcmd, ch->GetPoint(subcmd) + nPoint); ch->ComputePoints(); ch->PointChange(subcmd, 0); ch->PointChange(POINT_STAT, -nPoint); ch->ComputePoints(); } } This is the original code from the source... From what I understand of this lines: case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > 90) { nPoint = 90 - ch->GetPoint(POINT_HT); } break; If you try with more than 90 points it only goes up to 90 no matter what... This is the original code, this is mine: ACMD(do_stat_plus_amount) { char szPoint[256]; one_argument(argument, szPoint, sizeof(szPoint)); if (*szPoint == '\0') return; if (ch->IsPolymorphed()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다.")); return; } int nRemainPoint = ch->GetPoint(POINT_STAT); if (nRemainPoint <= 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 없습니다.")); return; } int nPoint = 0; str_to_number(nPoint, szPoint); if (nRemainPoint < nPoint) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 적습니다.")); return; } if (nPoint < 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("값을 잘못 입력하였습니다.")); return; } switch (subcmd) { case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > gPlayerMaxHT) { nPoint = gPlayerMaxHT - ch->GetPoint(POINT_HT); } break; case POINT_IQ : // 지능 if (nPoint + ch->GetPoint(POINT_IQ) > gPlayerMaxIQ) { nPoint = gPlayerMaxIQ - ch->GetPoint(POINT_IQ); } break; case POINT_ST : // 근력 if (nPoint + ch->GetPoint(POINT_ST) > gPlayerMaxST) { nPoint = gPlayerMaxST - ch->GetPoint(POINT_ST); } break; case POINT_DX : // 민첩 if (nPoint + ch->GetPoint(POINT_DX) > gPlayerMaxDX) { nPoint = gPlayerMaxDX - ch->GetPoint(POINT_DX); } break; default : ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("명령어의 서브 커맨드가 잘못 되었습니다.")); return; break; } if (nPoint != 0) { ch->SetRealPoint(subcmd, ch->GetRealPoint(subcmd) + nPoint); ch->SetPoint(subcmd, ch->GetPoint(subcmd) + nPoint); ch->ComputePoints(); ch->PointChange(subcmd, 0); ch->PointChange(POINT_STAT, -nPoint); ch->ComputePoints(); } } gPlayerMaxHT, gPlayerMaxIQ, gPlayerMaxST, gPlayerMaxDX This are global variables defined by config, soo, ignore them... Link to comment Share on other sites More sharing options...
.Rise 18 Posted March 5, 2018 Author Share Posted March 5, 2018 10 minutes ago, charparodar said: ACMD(do_stat_plus_amount) { char szPoint[256]; one_argument(argument, szPoint, sizeof(szPoint)); if (*szPoint == '\0') return; if (ch->IsPolymorphed()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다.")); return; } int nRemainPoint = ch->GetPoint(POINT_STAT); if (nRemainPoint <= 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 없습니다.")); return; } int nPoint = 0; str_to_number(nPoint, szPoint); if (nRemainPoint < nPoint) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 적습니다.")); return; } if (nPoint < 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("값을 잘못 입력하였습니다.")); return; } switch (subcmd) { case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > 90) { nPoint = 90 - ch->GetPoint(POINT_HT); } break; case POINT_IQ : // 지능 if (nPoint + ch->GetPoint(POINT_IQ) > 90) { nPoint = 90 - ch->GetPoint(POINT_IQ); } break; case POINT_ST : // 근력 if (nPoint + ch->GetPoint(POINT_ST) > 90) { nPoint = 90 - ch->GetPoint(POINT_ST); } break; case POINT_DX : // 민첩 if (nPoint + ch->GetPoint(POINT_DX) > 90) { nPoint = 90 - ch->GetPoint(POINT_DX); } break; default : ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("명령어의 서브 커맨드가 잘못 되었습니다.")); return; break; } if (nPoint != 0) { ch->SetRealPoint(subcmd, ch->GetRealPoint(subcmd) + nPoint); ch->SetPoint(subcmd, ch->GetPoint(subcmd) + nPoint); ch->ComputePoints(); ch->PointChange(subcmd, 0); ch->PointChange(POINT_STAT, -nPoint); ch->ComputePoints(); } } This is the original code from the source... From what I understand of this lines: case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > 90) { nPoint = 90 - ch->GetPoint(POINT_HT); } break; If you try with more than 90 points it only goes up to 90 no matter what... This is the original code, this is mine: ACMD(do_stat_plus_amount) { char szPoint[256]; one_argument(argument, szPoint, sizeof(szPoint)); if (*szPoint == '\0') return; if (ch->IsPolymorphed()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다.")); return; } int nRemainPoint = ch->GetPoint(POINT_STAT); if (nRemainPoint <= 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 없습니다.")); return; } int nPoint = 0; str_to_number(nPoint, szPoint); if (nRemainPoint < nPoint) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("남은 스탯 포인트가 적습니다.")); return; } if (nPoint < 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("값을 잘못 입력하였습니다.")); return; } switch (subcmd) { case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > gPlayerMaxHT) { nPoint = gPlayerMaxHT - ch->GetPoint(POINT_HT); } break; case POINT_IQ : // 지능 if (nPoint + ch->GetPoint(POINT_IQ) > gPlayerMaxIQ) { nPoint = gPlayerMaxIQ - ch->GetPoint(POINT_IQ); } break; case POINT_ST : // 근력 if (nPoint + ch->GetPoint(POINT_ST) > gPlayerMaxST) { nPoint = gPlayerMaxST - ch->GetPoint(POINT_ST); } break; case POINT_DX : // 민첩 if (nPoint + ch->GetPoint(POINT_DX) > gPlayerMaxDX) { nPoint = gPlayerMaxDX - ch->GetPoint(POINT_DX); } break; default : ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("명령어의 서브 커맨드가 잘못 되었습니다.")); return; break; } if (nPoint != 0) { ch->SetRealPoint(subcmd, ch->GetRealPoint(subcmd) + nPoint); ch->SetPoint(subcmd, ch->GetPoint(subcmd) + nPoint); ch->ComputePoints(); ch->PointChange(subcmd, 0); ch->PointChange(POINT_STAT, -nPoint); ch->ComputePoints(); } } gPlayerMaxHT, gPlayerMaxIQ, gPlayerMaxST, gPlayerMaxDX This are global variables defined by config, soo, ignore them... Ok.. I have another code of this function.. Sorry.. If I helped you, do not forget to press "Thanks" button! Link to comment Share on other sites More sharing options...
Recommended Posts