HerculesWS / Hercules

Hercules is a collaborative software development project revolving around the creation of a robust massively multiplayer online role playing game (MMORPG) server package. Written in C, the program is very versatile and provides NPCs, warps and modifications. The project is jointly managed by a group of volunteers located around the world as well as a tremendous community providing QA and support. Hercules is a continuation of the original Athena project.
http://herc.ws
GNU General Public License v3.0
900 stars 758 forks source link

showvending/roomshop/chatvending/chatshop/etc. #1777

Closed Likeeit closed 7 years ago

Likeeit commented 7 years ago

There is still no command, in any emulator, that shows a store chat on top of the NPC and this can be solved with a simple code.

/*=====================================================
* Créditos pelo código é para CrushTheMoonGuy e Holy. *
* Atualizado para revisão atual do brAthena por Tidus.* 
*----------------------------------------------------*/

diff --git a/src/map/clif.c b/src/map/clif.c
index 7ec7882..d57240f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4289,6 +4290,8 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) {
                    clif->specialeffect_single(bl,423,sd->fd);
                else if( nd->size == SZ_MEDIUM )
                    clif->specialeffect_single(bl,421,sd->fd);
+               if( nd->vend.vends == true )
+                   clif->showvendingboard( &nd->bl, nd->vend.vending, sd->fd );
            }
            break;
        case BL_MOB:
diff --git a/src/map/npc.h b/src/map/npc.h
index 34daf4c..af01866 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -125,6 +130,12 @@ struct npc_data {
            char killer_name[NAME_LENGTH];
        } tomb;
    } u;
+
+       struct {
+       char vending[NAME_LENGTH+1]; //vending name
+       bool vends; //does he vend?
+       } vend;
+
 };

diff --git a/src/map/script.c b/src/map/script.c
index c983fa7..5f3cd94 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -17943,6 +17987,51 @@ int buildin_instance_warpall_sub(struct block_list *bl,va_list ap) {
    return true;
 }

+BUILDIN(showvend)
+{
+   struct npc_data *nd;
+   const char * message;
+   const char * name;
+   unsigned char buf[NAME_LENGTH+1];
+   int flag;
+
+   name = script_getstr( st, 2 );
+   flag = script_getnum( st, 3 );
+
+   if( flag && !script_hasdata( st, 4 ) ) {
+   ShowError( "showvend: want to create vendingboard without name.\n" );
+   script_reportsrc( st );
+   st->state = END; //Script stops
+   return -1;
+   }
+   else if( flag )
+   message = script_getstr( st, 4 );
+
+   nd = npc->name2id( name );
+
+   if( nd == NULL ) {
+   ShowError( "showvend: no npc found!\n" );
+   script_pushint( st, 0 ); //Fail return 0
+   return 0;
+   }
+
+   switch( flag ) {
+   case 0:
+   clif->closevendingboard( &nd->bl, 0 );
+   nd->vend.vends = false;
+   break;
+   default:
+   memcpy( buf, message, NAME_LENGTH + 1 );
+   clif->showvendingboard( &nd->bl, buf, 0 );
+   nd->vend.vends = true;
+   memcpy( nd->vend.vending, message, NAME_LENGTH + 1 );
+   break;
+   }
+
+   script_pushint( st, 1 ); //Success return 1
+   return 0;
+}
+
 /*==========================================
  * Custom Fonts
  *------------------------------------------*/
@@ -21361,6 +21364,10 @@ void script_parse_builtin(void) {

        BUILDIN_DEF(channelmes, "ss"),
        BUILDIN_DEF(_,"s"),
+
+       /* brAthena - Modificações */
+       BUILDIN_DEF(showvend, "si?" ),
+       
    };
    int i, len = ARRAYLENGTH(BUILDIN);
    RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
diff --git a/src/map/vending.c b/src/map/vending.c
index e07d6bd..3740b9c 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -22,6 +22,7 @@
 #include "clif.h"
 #include "itemdb.h"
 #include "log.h"
+#include "npc.h"
 #include "map.h"
 #include "npc.h"
 #include "path.h"
@@ -73,8 +74,25 @@ void vending_closevending(struct map_session_data* sd) {
  *------------------------------------------*/
 void vending_vendinglistreq(struct map_session_data* sd, unsigned int id) {
    struct map_session_data* vsd;
+   struct npc_data *nd_sd;
    nullpo_retv(sd);

+   if( nd_sd = (TBL_NPC*) map->id2bl( id ) ) { //It's an NPC
+   if( nd_sd->vend.vends == true ) {
+       char event_name[64 + 23 + 1];
+   if( nd_sd->subtype == CASHSHOP ) //Act as if it was clicked
+       npc->click( sd, nd_sd );
+   if( nd_sd->subtype == SHOP ) //Open Buy-Windows directly
+       npc->buysellsel( sd, nd_sd->bl.id, 0 );
+   if( nd_sd->subtype == SCRIPT ) { //Trigger OnVendingClick event
+       sprintf( event_name, "%s::OnVendingClick", &nd_sd->name );
+       npc->event( sd, event_name, 0 );
+       return;
+       }
+   }
+   return; //WARP will just return
+}
+
    if( (vsd = map->id2sd(id)) == NULL )
        return;
    if( !vsd->state.vending )
Likeeit commented 7 years ago

Script

prontera,174,91,3   script  namenpc 4_F_JOB_BLACKSMITH,{
OnVendingClick:
callshop "open",1;   
end;

OnInit:
showvend( "namenpc", 1, "nameshop" );
end;
}
-   shop    open    -1,15068:0,15138:0,15073:0
Helianthella commented 7 years ago

We can't just grab any code and shove it in; it needs a compatible license. Is this licensed under GPL?

Likeeit commented 7 years ago

The code does not have to be exactly that, just an example. But yes, this was created for a Brazilian emulator that is forkado of Hercules, and is of free use with the due credits, as I put above.

Helianthella commented 7 years ago

@Likeeit giving credits does not automagically make the code GPL-compatible

tlacson7 commented 7 years ago

i just hope to see this as plugin instead.

Likeeit commented 7 years ago

@mekolat No code created above the GPL license can become private. And as I said before, the code does not have to be exactly that, what I meant by opening this issue, is that we need this functionality in the emulator.

Emistry commented 7 years ago

It this something like a normal NPC create a vending header like the normal merchant did?

I like this idea, few years ago, I was trying to create this systen, but failed, no idea how the source work. Failed and abandoned it. But if you wish to get something implement into the emulators, its better if you do it by submit a pull request, which speed up the process to review and implementing it.

But frankly speaking, I think we should always all hard-coded values as much as possible. Like this... sprintf( event_name, "%s::OnVendingClick", &nd_sd->name ); We can just have the NPC set to trigger whatever label they want, which give much more flexibility to other member who wanted to use this.

For example:

prontera,174,91,3   script  npc_name    4_F_KAFRA01,{
OnWhateverLabel:
    callshop "open",1;   
    end;

OnInit:
    create_vending_header( "<vending_title>", "<shop_npc_name>", "npc_name::OnWhateverLabel" );
    end;
}
sagunkho commented 7 years ago

Umm, Hercules has plugins for people to go ahead and add whatever custom source they'd like. We want to keep this sort of unnecessary stuff out of the main code.