Jump to content

joecalis

Members
  • Posts

    64
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by joecalis

  1. That's because Summoner isn't counted as either of those, according to the status.cpp file at status_calc_pc_ summoner class is considered as RC_BRUTE: base_status->race = ((battle_config.summoner_trait&1) && (sd->class_&MAPID_BASEMASK) == MAPID_SUMMONER) ? RC_BRUTE : RC_PLAYER; Maybe you could tinker with that. Or just change the summoner trait from player.conf // Adjust the summoner class' special traits. // 0: Summoners behave like other classes. // 1: Summoners belong to brute race instead of demi-human // 2: Summoners are small size instead of medium // 3: Both of the above (official value) summoner_trait: 3
  2. Does anyone still have the file or download link for Ricky92's Granny Converter that is used to convert .gr2 version 2.6.0.10 to 2.1.0.5 which was used in these projects: Tutorial - Importing custom Granny GR2 in RO, Animated 3D Monsters in RO The download links that was in those project are dead so I would really appreciate it if anyone can share the working download link, thank you...
  3. So I just noticed a problem with calling a dynamic shop, it seems that if you call a shop through a script, your character will be able to move freely and get away from the NPC that called it, but if you buy items while far from the NPC, it causes errors and frozen characters. So is there anyway of preventing this from happening? I have tried blocking the characters movement using "pcblockmove" but the problem with that is if you close the shop without purchasing your character will stay stuck. I also tried blocking the movement with a "mes" script command but once you close the "mes" window you'll be able to move freely again. Please tell me if there is another way to prevent this, or do I have to go to the src files to implement this. Thank you.
  4. So I tried modifying my vending skill to use Cashpoints instead of Zeny and coded it like this: vending.c at "vending_purchasereq" /*========================================== * Purchase item(s) from a shop *------------------------------------------*/ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid, const uint8* data, int count) { int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING]; double z; double cashPoints; struct s_vending vend[MAX_VENDING]; // against duplicate packets struct map_session_data* vsd = map->id2sd(aid); nullpo_retv(sd); if( vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id ) return; // invalid shop if( vsd->vender_id != uid ) { // shop has changed clif->buyvending(sd, 0, 0, 6); // store information was incorrect return; } if( !searchstore->queryremote(sd, aid) && ( sd->bl.m != vsd->bl.m || !check_distance_bl(&sd->bl, &vsd->bl, AREA_SIZE) ) ) return; // shop too far away searchstore->clearremote(sd); if( count < 1 || count > MAX_VENDING || count > vsd->vend_num ) return; // invalid amount of purchased items blank = pc->inventoryblank(sd); //number of free cells in the buyer's inventory // duplicate item in vending to check hacker with multiple packets memcpy(&vend, &vsd->vending, sizeof(vsd->vending)); // copy vending list // some checks z = 0.; // zeny counter w = 0; // weight counter for( i = 0; i < count; i++ ) { short amount = *(uint16*)(data + 4*i + 0); short idx = *(uint16*)(data + 4*i + 2); idx -= 2; if( amount <= 0 ) return; // check of item index in the cart if( idx < 0 || idx >= MAX_CART ) return; ARR_FIND( 0, vsd->vend_num, j, vsd->vending[j].index == idx ); if( j == vsd->vend_num ) return; //picked non-existing item else vend_list[i] = j; z += ((double)vsd->vending[j].value * (double)amount); /*if( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY ) { clif->buyvending(sd, idx, amount, 1); // you don't have enough zeny return; }*/ cashPoints = pc_readaccountreg(sd,script->add_str("#CASHPOINTS")); if( z > cashPoints || z < 0. || z > (double)MAX_ZENY ) { clif->buyvending(sd, idx, amount, 1); // you don't have enough zeny return; } cashPoints = pc_readaccountreg(vsd,script->add_str("#CASHPOINTS")); if( z + (double)vsd->cashPoints > (double)MAX_ZENY && !battle_config.vending_over_max ) { clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow return; } w += itemdb_weight(vsd->status.cart[idx].nameid) * amount; if( w + sd->weight > sd->max_weight ) { clif->buyvending(sd, idx, amount, 2); // you can not buy, because overweight return; } //Check to see if cart/vend info is in sync. if( vend[j].amount > vsd->status.cart[idx].amount ) vend[j].amount = vsd->status.cart[idx].amount; // if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples). // here, we check cumulative amounts if( vend[j].amount < amount ) { // send more quantity is not a hack (an other player can have buy items just before) clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity return; } vend[j].amount -= amount; switch( pc->checkadditem(sd, vsd->status.cart[idx].nameid, amount) ) { case ADDITEM_EXIST: break; //We'd add this item to the existing one (in buyers inventory) case ADDITEM_NEW: new_++; if (new_ > blank) return; //Buyer has no space in his inventory break; case ADDITEM_OVERAMOUNT: return; //too many items } } //pc->payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd); pc->paycash(sd, (int)z, 0); /* if( battle_config.vending_tax ) z -= z * (battle_config.vending_tax/10000.); */ //pc->getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd); pc->getcash(vsd, (int)z, 0); for( i = 0; i < count; i++ ) { short amount = *(uint16*)(data + 4*i + 0); short idx = *(uint16*)(data + 4*i + 2); idx -= 2; // vending item pc->additem(sd, &vsd->status.cart[idx], amount, LOG_TYPE_VENDING); vsd->vending[vend_list[i]].amount -= amount; pc->cart_delitem(vsd, idx, amount, 0, LOG_TYPE_VENDING); clif->vendingreport(vsd, idx, amount); //print buyer's name if( battle_config.buyer_name ) { char temp[256]; sprintf(temp, msg_txt(265), sd->status.name); clif_disp_onlyself(vsd,temp,strlen(temp)); } } // compact the vending list for( i = 0, cursor = 0; i < vsd->vend_num; i++ ) { if( vsd->vending[i].amount == 0 ) continue; if( cursor != i ) { // speedup vsd->vending[cursor].index = vsd->vending[i].index; vsd->vending[cursor].amount = vsd->vending[i].amount; vsd->vending[cursor].value = vsd->vending[i].value; } cursor++; } vsd->vend_num = cursor; //Always save BOTH: buyer and customer if( map->save_settings&2 ) { chrif->save(sd,0); chrif->save(vsd,0); } //check for @AUTOTRADE users [durf] if( vsd->state.autotrade ) { //see if there is anything left in the shop ARR_FIND( 0, vsd->vend_num, i, vsd->vending[i].amount > 0 ); if( i == vsd->vend_num ) { //Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex] vending->close(vsd); map->quit(vsd); //They have no reason to stay around anymore, do they? } else pc->autotrade_update(vsd,PAUC_REFRESH); } } Everything is working fine, when I buy items it costs Cashpoints and the vendor gets Cashpoints too but the problem is, when You drag and drop items you want to buy it checks the price as Zeny instead of Cashpoints, so if you have 0 zeny when you try to buy something, the message "You do not have enough Zeny" shows at the chat and it wont transfer to the "Buying box". How do I make it so that It checks #CASHPOINTS instead of Zeny when I drag and drop items to the "Buying box".
  5. Can anyone please tell me how to edit the "Sales List" message shown when vending, it looks like this: I want to change the text like so, ~~~~~~~~~~Shop List~~~~~~~~~~ <Item Name> : <Price> Points ea Current Points : <#CASHPOINTS> ~~~~~~~~~~~~~~~~~~~~~~~~~~~ I tried looking for that in msgstringtable.txt, all the lua files, vending.c, clif.c, and messages.conf but I just can't seem to find it.
  6. That will not appear ever unless you added an npc with a script code like that. So if you implement this, You can make different npc with "mobexists(<Mob ID>)" function. e.g. prontera,150,150,4 script Monster Spawn Check 405,{ set @npcname$,"[^ff0000 Monster Spawn Check ^000000]"; mes @npcname$; mes "Put the monster ID you would like to check."; next; input @mobid; if(@mobid<=0){ mes @npcname$; mes "Please put in a real ID"; close } else if(!mobexists(@mobid)){ mes @npcname$; mes "That monster does not exists or spawn naturally."; close; } else { mes @npcname$; mes "Yes "+getmonsterinfo(@mobinfo,0)+" exists and spawns naturally."; close } }
  7. Its not an @command, its a script command meaning it will only work for npc scripts like the one shown in the example.
  8. Yeah but (strmobinfo) doesn't track if the mob has natural spawn or not like event monsters and stuff ^^ And no sorry, I don't know how to create a diff. I'm a newbie at this kind of things
  9. Hallo, hallo everyone. This is going to be my very first release here, so I hope it can be useful. So basically I made a script command that checks whether the monster stated exists in the mob_db or spawns naturally (Some monsters doesn't spawn naturally but listed on the mob_db). So here's how it works. if(mobexists(1002)){ // It works with mob name too "mobexists("Poring")" mes "Yes its a Poring, of course exists foo!"; close; } else { mes "No that monster does not exist or maybe it just doesn't spawn."; mes "Meh! What ever floats your boat..."; close; } If the mob stated exists it returns a value of 1 if not it returns -1 or 0. So if you want this script command here's what you do: Step 1 - open src\map\script.c Step 2 - Find this line. BUILDIN_FUNC(checkvending) Step 3 - Right above it, just slap this code right in so it would look like this. Raw Code BUILDIN_FUNC(mobexists) //added code start { struct mob_db *mob, *mob_array[MAX_SEARCH]; const char* mob_id = script_getstr(st,2); int count; int i, j, k; if (!mob_id){ ShowError("buildin_mobexists: No Monster ID set."); return -1; } // If monster identifier/name argument is a name if ((i = mobdb_checkid(atoi(mob_id)))) { mob_array[0] = mob_db(i); count = 1; } else count = mobdb_searchname_array(mob_array, MAX_SEARCH, mob_id); if (!count) { script_pushint(st,-1); } if (count > MAX_SEARCH) { count = MAX_SEARCH; } for (k = 0; k < count; k++) { mob = mob_array[k]; for (i = 0; i < ARRAYLENGTH(mob->spawn) && mob->spawn[i].qty; i++) { j = map_mapindex2mapid(mob->spawn[i].mapindex); if (j < 0) continue; } if (i == 0) { script_pushint(st,-1); } else { script_pushint(st,1); } } return 0; } //added code end BUILDIN_FUNC(checkvending) Step 4 - Find this code. BUILDIN_DEF(getmonsterinfo,"ii"), Step 5 - Right below it slap this code right in too so it would look like this. BUILDIN_DEF(getmonsterinfo,"ii"), BUILDIN_DEF(mobexists,"i"), //added code Step 6 - Save and Recompile and Done. So there you go folks, just a little bit of finding and a little slapping here and there and your good to go. Reply to this thread if you're having any problems/errors.
  10. joecalis

    Get Skill

    I was wondering if someone could modify the "skill" or "addtoskill" command to be available to give a permanent skill at level 0 and can be upgraded by skill points.
×
×
  • Create New...