Index: src/map/clif.c =================================================================== --- src/map/clif.c (revision 15869) +++ src/map/clif.c (working copy) @@ -14047,9 +14047,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++ ) @@ -14080,14 +14080,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 15869) +++ src/map/npc.c (working copy) @@ -1356,13 +1356,18 @@ } price = nd->u.shop.shop_item[i].value * amount; - if( points > price ) + 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) ) points = price; if( (sd->kafraPoints < points) || (sd->cashPoints < 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) ) { @@ -1723,8 +1728,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] - aFree(nd->u.shop.shop_item); + 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 ) { @@ -2059,6 +2067,7 @@ } if( !strcasecmp(w2,"cashshop") ) + if( !strcasecmp(w2,"shop") ) type = CASHSHOP; else type = SHOP; @@ -2119,6 +2128,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; @@ -2457,8 +2507,12 @@ 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; @@ -3295,7 +3349,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 15869) +++ 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 15869) +++ src/map/script.c (working copy) @@ -15886,6 +15886,78 @@ BUILDIN_FUNC(deletepset); #endif +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; +} + + + /// script command definitions /// for an explanation on args, see add_buildin_func struct script_function buildin_func[] = {