#Script command used to change the variables a specific cash shop uses (#CASHPOINTS and #KAFRAPOINTS by default). #Usage: #setcashpoints "",""; #setfreepoints "",""; #In NPC Declaration, use cashshop(,) in place of cashshop. #NOTE: this declaration is case sensitive, and will only work with cashshop in all lowercase. #Sample NPC: #prontera,155,176,5 cashshop(#ctf_event_points,#global_event_points) CTF Rewards 83,502:5,503:1 Index: src/map/clif.c =================================================================== --- src/map/clif.c (revision 15933) +++ src/map/clif.c (working copy) @@ -14060,9 +14060,9 @@ WFIFOHEAD(fd,offset+nd->u.shop.count*11); WFIFOW(fd,0) = 0x287; WFIFOW(fd,2) = offset+nd->u.shop.count*11; - WFIFOL(fd,4) = sd->cashPoints; // Cash Points + WFIFOL(fd,4) = pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype); // Cash Points #if PACKETVER >= 20070711 - WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points + WFIFOL(fd,8) = pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype);; // Kafra Points #endif for( i = 0; i < nd->u.shop.count; i++ ) @@ -14093,14 +14093,18 @@ void clif_cashshop_ack(struct map_session_data* sd, int error) { int fd = sd->fd; + struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid); + if( !nd || nd->subtype != CASHSHOP ) + error = 1; + WFIFOHEAD(fd, packet_len(0x289)); WFIFOW(fd,0) = 0x289; - WFIFOL(fd,2) = sd->cashPoints; + WFIFOL(fd,2) = pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype); #if PACKETVER < 20070711 WFIFOW(fd,6) = TOW(error); #else - WFIFOL(fd,6) = sd->kafraPoints; + WFIFOL(fd,6) = pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype); WFIFOW(fd,10) = TOW(error); #endif WFIFOSET(fd, packet_len(0x289)); Index: src/map/npc.c =================================================================== --- src/map/npc.c (revision 15933) +++ src/map/npc.c (working copy) @@ -1275,9 +1275,15 @@ if( points > vt ) points = vt; // Payment Process ---------------------------------------------------- - if( sd->kafraPoints < points || sd->cashPoints < (vt - points) ) - return 6; - pc_paycash(sd,vt,points); + if( (pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype) < points) || (pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype) < (vt - points)) ) + return 6; + + if (!strcasecmp(nd->u.shop.cash_var,"#CASHPOINTS") && !strcasecmp(nd->u.shop.point_var,"#KAFRAPOINTS")) + pc_paycash(sd,vt,points); + else { + pc_setregistry(sd,nd->u.shop.cash_var,pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype) - (vt - points),nd->u.shop.cash_vartype); + pc_setregistry(sd,nd->u.shop.point_var,pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype) - points,nd->u.shop.point_vartype); + } // Delivery Process ---------------------------------------------------- for( i = 0; i < count; i++ ) @@ -1385,11 +1391,16 @@ price = nd->u.shop.shop_item[i].value * amount; if( points > price ) points = price; - - if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) ) + + if( (pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype) < points) || (pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype) < (price - points)) ) return 6; - pc_paycash(sd, price, points); + if (!strcasecmp(nd->u.shop.cash_var,"#CASHPOINTS") && !strcasecmp(nd->u.shop.point_var,"#KAFRAPOINTS")) + pc_paycash(sd, price, points); + else { + pc_setregistry(sd,nd->u.shop.cash_var,pc_readregistry(sd,nd->u.shop.cash_var,nd->u.shop.cash_vartype) - (price - points),nd->u.shop.cash_vartype); + pc_setregistry(sd,nd->u.shop.point_var,pc_readregistry(sd,nd->u.shop.point_var,nd->u.shop.point_vartype) - points,nd->u.shop.point_vartype); + } if( !pet_create_egg(sd, nameid) ) { @@ -1750,8 +1761,11 @@ npc_chat_finalize(nd); // deallocate npc PCRE data structures #endif - if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao] + if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0){ //src check for duplicate shops [Orcao] aFree(nd->u.shop.shop_item); + aFree(nd->u.shop.cash_var); + aFree(nd->u.shop.point_var); + } else if( nd->subtype == SCRIPT ) { @@ -2085,10 +2099,10 @@ m = map_mapname2mapid(mapname); } - if( !strcasecmp(w2,"cashshop") ) + if( !strcasecmp(w2,"shop") ) + type = SHOP; + else type = CASHSHOP; - else - type = SHOP; p = strchr(w4,','); for( i = 0; i < ARRAYLENGTH(items) && p; ++i ) @@ -2146,6 +2160,47 @@ nd->class_ = m==-1?-1:atoi(w4); nd->speed = 200; + //assign cash shop var stuff here + if (type == CASHSHOP && !strcasecmp(w2,"cashshop") ){ + nd->u.shop.cash_var = aStrdup("#CASHPOINTS"); + nd->u.shop.point_var = aStrdup("#KAFRAPOINTS"); + nd->u.shop.cash_vartype = 2; + nd->u.shop.point_vartype = 2; + } + else if (type == CASHSHOP) { //Variables were defined as cashshop({,}) + char cashvarname_temp[32]; + char pointvarname_temp[32]; + if (sscanf(w2,"cashshop(%32[^,],%32[^)])",cashvarname_temp,pointvarname_temp) == 2){ + nd->u.shop.cash_var = aStrdup(cashvarname_temp); + nd->u.shop.point_var = aStrdup(pointvarname_temp); + } + else if (sscanf(w2,"cashshop(%32[^)])",cashvarname_temp) == 1){ + nd->u.shop.cash_var = aStrdup(cashvarname_temp); + nd->u.shop.point_var = aStrdup("#KAFRAPOINTS"); + } + else{ + nd->u.shop.cash_var = aStrdup("#CASHPOINTS"); + nd->u.shop.point_var = aStrdup("#KAFRAPOINTS"); + ShowError("npc_parse_shop: Cash Shop with unknown w2 \"%s\", assuming normal variables\n",w2); + } + + //get variable types + if (nd->u.shop.cash_var[0] == '#' && nd->u.shop.cash_var[1] == '#') + nd->u.shop.cash_vartype = 1; + else if (nd->u.shop.cash_var[0] == '#') + nd->u.shop.cash_vartype = 2; + else + nd->u.shop.cash_vartype = 3; + + + if (nd->u.shop.point_var[0] == '#' && nd->u.shop.point_var[1] == '#') + nd->u.shop.point_vartype = 1; + else if (nd->u.shop.point_var[0] == '#') + nd->u.shop.point_vartype = 2; + else + nd->u.shop.point_vartype = 3; + } + ++npc_shop; nd->bl.type = BL_NPC; nd->subtype = type; @@ -2483,9 +2538,13 @@ nd->u.scr.label_list = dnd->u.scr.label_list; nd->u.scr.label_list_num = dnd->u.scr.label_list_num; break; - + + case CASHSHOP: + nd->u.shop.cash_var = dnd->u.shop.cash_var; + nd->u.shop.cash_vartype = dnd->u.shop.cash_vartype; + nd->u.shop.point_var = dnd->u.shop.point_var; + nd->u.shop.point_vartype = dnd->u.shop.point_vartype; case SHOP: - case CASHSHOP: ++npc_shop; nd->u.shop.shop_item = dnd->u.shop.shop_item; nd->u.shop.count = dnd->u.shop.count; @@ -3322,7 +3381,7 @@ { p = npc_parse_warp(w1,w2,w3,w4, p, buffer, filepath); } - else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3 ) + else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop") || (i=0, sscanf(w2,"cashshop%n",&i), (i > 0 && w2[i] == '('))) && count > 3 ) { p = npc_parse_shop(w1,w2,w3,w4, p, buffer, filepath); } Index: src/map/npc.h =================================================================== --- src/map/npc.h (revision 15933) +++ src/map/npc.h (working copy) @@ -56,6 +56,8 @@ struct { struct npc_item_list* shop_item; int count; + char *cash_var, *point_var; + short cash_vartype, point_vartype; //1 = ##, 2 = #, 3 = Character } shop; struct { short xs,ys; // OnTouch area radius Index: src/map/script.c =================================================================== --- src/map/script.c (revision 15933) +++ src/map/script.c (working copy) @@ -15879,6 +15879,78 @@ return 0; } + +BUILDIN_FUNC(setcashpoints) +{ + const char* npcname = script_getstr(st,2); + struct npc_data* nd = npc_name2id(npcname); + const char* newcashvar = script_getstr(st,3); + size_t len; + + if( !nd || nd->subtype != CASHSHOP ) + { //Not found. + script_pushint(st,0); + return 0; + } + + len = strlen(newcashvar)+1; + if (len < 32){ + RECREATE(nd->u.shop.cash_var, char, len); + memcpy(nd->u.shop.cash_var, newcashvar, len*sizeof(char)); + } + else{ //variable name too long + script_pushint(st,0); + ShowError("setcashpoints: Failed to set the cash variable of %s to %s due to character length.\n",npcname,newcashvar); + return 0; + } + + if (newcashvar[0] == '#' && newcashvar[1] == '#') + nd->u.shop.cash_vartype = 1; + else if (newcashvar[0] == '#') + nd->u.shop.cash_vartype = 2; + else + nd->u.shop.cash_vartype = 3; + + script_pushint(st,1); + return 0; +} + +BUILDIN_FUNC(setfreepoints) +{ + const char* npcname = script_getstr(st,2); + struct npc_data* nd = npc_name2id(npcname); + const char* newcashvar = script_getstr(st,3); + size_t len; + + if( !nd || nd->subtype != CASHSHOP ) + { //Not found. + script_pushint(st,0); + return 0; + } + + len = strlen(newcashvar)+1; + if (len < 32){ + RECREATE(nd->u.shop.point_var, char, len); + memcpy(nd->u.shop.point_var, newcashvar, len*sizeof(char)); + } + else{ //variable name too long + script_pushint(st,0); + ShowError("setfreepoints: Failed to set the kafrapoints variable of %s to %s due to character length.\n",npcname,newcashvar); + return 0; + } + + if (newcashvar[0] == '#' && newcashvar[1] == '#') + nd->u.shop.point_vartype = 1; + else if (newcashvar[0] == '#') + nd->u.shop.point_vartype = 2; + else + nd->u.shop.point_vartype = 3; + + script_pushint(st,1); + return 0; +} + + // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT BUILDIN_FUNC(defpattern); @@ -16261,6 +16333,8 @@ BUILDIN_DEF(pushpc,"ii"), BUILDIN_DEF(buyingstore,"i"), BUILDIN_DEF(searchstores,"ii"), + BUILDIN_DEF(setcashpoints,"ss"), + BUILDIN_DEF(setfreepoints,"ss"), BUILDIN_DEF(showdigit,"i?"), // WoE SE BUILDIN_DEF(agitstart2,""),