Emistry

Utility: Campfire

Recommended Posts

2 hours ago, Phaige said:

@Emistry How to change the effect instead of healing into other buff effects/boost effects.

addrid + sc_start

Share this post


Link to post
Share on other sites

Please show me!!Where i wrong? When i apply your code with my src? @Emistry

[ I really like your campfire system ]

My script.inc:

// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder

/**
 * Custom Script Commands
 * Place the body of custom script commands in this file.
 * Format:
 *	BUILDIN_FUNC(command_name)
 *	{
 *		<code>;
 *	}
 **/

//BUILDIN_FUNC(example)
//{
//	ShowInfo("buildin_example: It works!\n");
//	script_pushint(st,1);
//	return 0;
//}

/*==========================================
 * Duplicate any npc on live server
 * duplicatenpc "<Source NPC name>","<New NPC shown name>","<New NPC hidden name>","<mapname>",<map_x>,<map_y>,<dir>{, spriteid{, map_xs, map_ys}}};
 *------------------------------------------*/
BUILDIN_FUNC(duplicatenpc)
{
   int map_x = script_getnum(st, 6);
   int map_y = script_getnum(st, 7);
   int dir = script_getnum(st, 8);
   int spriteid, map_xs = -1, map_ys = -1, sourceid, type, mapid, i;
   const char *sourcename = script_getstr(st, 2);
   const char *new_shown_name = script_getstr(st, 3);
   const char *new_hidden_name = script_getstr(st, 4);
   const char *mapname = script_getstr(st, 5);

   char new_npc_name[24] = "";
   struct npc_data *nd_source, *nd_target;

   if(script_hasdata(st, 10))
       map_xs = (script_getnum(st, 10) < -1) ? -1 : script_getnum(st, 10);

   if(script_hasdata(st, 11))
       map_ys = (script_getnum(st, 11) < -1) ? -1 : script_getnum(st, 10);

   if(map_xs == -1 && map_ys != -1)
       map_xs = 0;

   if(map_xs != - 1 && map_ys == -1)
       map_ys = 0;

   if(strlen(new_shown_name) + strlen(new_hidden_name) > NAME_LENGTH) {
       ShowError("buildin_duplicatenpc: New NPC shown name + New NPC hidden name is too long (max %d chars). (%s)\n", sourcename, NAME_LENGTH);
       script_pushint(st, 0);
       return SCRIPT_CMD_FAILURE;
   }

   nd_source = npc_name2id(sourcename);

   if(script_hasdata(st, 9))
       spriteid = (script_getnum(st, 9) < -1) ? -1 : script_getnum(st, 9);
   else
       spriteid = nd_source->class_;

   if(nd_source == NULL) {
       ShowError("buildin_duplicatenpc: original npc not found for duplicate. (%s)\n", sourcename);
       script_pushint(st, 0);
       return SCRIPT_CMD_FAILURE;
   }
  
   sourceid = nd_source->bl.id;
   type = nd_source->subtype;
   mapid = map_mapname2mapid(mapname);

   if(mapid < 0) {
       ShowError("buildin_duplicatenpc: target map not found. (%s)\n", mapname);
       script_pushint(st, 0);
       return SCRIPT_CMD_FAILURE;
   }

   CREATE(nd_target, struct npc_data, 1);
  
   strcat(new_npc_name, new_shown_name);
   strncat(new_npc_name, "#", 1);
   strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));

   safestrncpy(nd_target->name, new_npc_name , sizeof(nd_target->name));
   safestrncpy(nd_target->exname, new_npc_name, sizeof(nd_target->exname));

   nd_target->bl.prev = nd_target->bl.next = NULL;
   nd_target->bl.m = mapid;
   nd_target->bl.x = map_x;
   nd_target->bl.y = map_y;
   nd_target->bl.id = npc_get_new_npc_id();
   nd_target->class_ = spriteid;
   nd_target->speed = 200;
   nd_target->src_id = sourceid;
   nd_target->bl.type = BL_NPC;
   nd_target->subtype = (enum npc_subtype)type;

   switch(type) {
       case NPCTYPE_SCRIPT:
           nd_target->u.scr.xs = map_xs;
           nd_target->u.scr.ys = map_ys;
           nd_target->u.scr.script = nd_source->u.scr.script;
           nd_target->u.scr.label_list = nd_source->u.scr.label_list;
           nd_target->u.scr.label_list_num = nd_source->u.scr.label_list_num;
           break;
       case NPCTYPE_SHOP:
       case NPCTYPE_CASHSHOP:
       case NPCTYPE_ITEMSHOP:
       case NPCTYPE_POINTSHOP:
       case NPCTYPE_MARKETSHOP:
           nd_target->u.shop.shop_item = nd_source->u.shop.shop_item;
           nd_target->u.shop.count = nd_source->u.shop.count;
           break;
       case NPCTYPE_WARP:
           if( !battle_config.warp_point_debug )
               nd_target->class_ = JT_WARPNPC;
           else
               nd_target->class_ = JT_GUILD_FLAG;
           nd_target->u.warp.xs = map_xs;
           nd_target->u.warp.ys = map_ys;
           nd_target->u.warp.mapindex = nd_source->u.warp.mapindex;
           nd_target->u.warp.x = nd_source->u.warp.x;
           nd_target->u.warp.y = nd_source->u.warp.y;
           nd_target->trigger_on_hidden = nd_source->trigger_on_hidden;
           break;
   }

   map_addnpc(mapid, nd_target);
   status_change_init(&nd_target->bl);
   unit_dataset(&nd_target->bl);
   nd_target->ud.dir = dir;
   npc_setcells(nd_target);
   map_addblock(&nd_target->bl);

   if(spriteid >= 0) {
       status_set_viewdata(&nd_target->bl, nd_target->class_);
       clif_spawn(&nd_target->bl);
   }

   strdb_put(npcname_db, nd_target->exname, nd_target);

   if(type == NPCTYPE_SCRIPT) {
       for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
           char* lname = nd_target->u.scr.label_list[i].name;
           int pos = nd_target->u.scr.label_list[i].pos;

           if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) {
               struct event_data* ev;
               char buf[NAME_LENGTH*2+3];
               snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd_target->exname, lname);

               CREATE(ev, struct event_data, 1);
               ev->nd = nd_target;
               ev->pos = pos;
               if(strdb_put(ev_db, buf, ev))
                   ShowWarning("npc_parse_duplicate : duplicate event %s (%s)\n", buf, nd_target->name);
           }
       }

       for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
           int t = 0, k = 0;
           char *lname = nd_target->u.scr.label_list[i].name;
           int pos = nd_target->u.scr.label_list[i].pos;
           if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
               struct npc_timerevent_list *te = nd_target->u.scr.timer_event;
               int j, k = nd_target->u.scr.timeramount;
               if (te == NULL)
                   te = (struct npc_timerevent_list *)aMalloc(sizeof(struct npc_timerevent_list));
               else
                   te = (struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
               for (j = 0; j < k; j++) {
                   if (te[j].timer > t) {
                       memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
                       break;
                   }
               }
               te[j].timer = t;
               te[j].pos = pos;
               nd_target->u.scr.timer_event = te;
               nd_target->u.scr.timeramount++;
           }
       }
       nd_target->u.scr.timerid = INVALID_TIMER;
   }

   script_pushint(st, 1);
   return SCRIPT_CMD_SUCCESS;
}

/*==========================================
 * Remove any npc duplicate on live server
 * duplicateremove "<NPC name>";
 *------------------------------------------*/
BUILDIN_FUNC(duplicateremove)
{
   struct npc_data *nd;

   if(script_hasdata(st, 2)) {
       nd = npc_name2id(script_getstr(st, 2));
       if(nd == NULL) {
           script_pushint(st, -1);
           return SCRIPT_CMD_FAILURE;
       }
   } else
       nd = (struct npc_data *)map_id2bl(st->oid);

   if(!nd->src_id)
       npc_unload_duplicates(nd);
   else
       npc_unload(nd,true);

   script_pushint(st, 1);
   return SCRIPT_CMD_SUCCESS;
}

My script_def.inc:

// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder

/**
 * Custom Script Commands
 * Place the definition of custom script commands in this file.
 * Format:
 *	BUILDIN_DEF(command_name,"parameters"),
 **/

//BUILDIN_DEF(example,""),
BUILDIN_DEF(duplicatenpc, "ssssiii???"),
BUILDIN_DEF(duplicateremove, "?"),

My npc.cpp,before add code:

http://001.jpg

My npc.cpp,after add code:

http://002.jpg

My npc.hpp:

http://003.jpg

 

Edited by JaranSwitch0101

Share this post


Link to post
Share on other sites
Posted (edited)

Do we need to assign a NPC sprite id for the campfire? 

Here:

-    script    Camp Fire::cf_main    FAKE_NPC,{ 

Do i need to change Campfire to 649? 

649 is the sprite i want to use

Also

I added the diffs as instructed. No errors encountered with the diffs. x2 Checked if diffs are added.

Added the scripts for each item with changing them to usable items.

It is not working for me. I am using the latest rathena atm.

 

Edited by Dev G Inc

Share this post


Link to post
Share on other sites

find the defailt NPC Sprite ID 10252 and replace it with whatever npc sprite you want.

Share this post


Link to post
Share on other sites
On 3/28/2019 at 4:44 PM, Emistry said:

find the defailt NPC Sprite ID 10252 and replace it with whatever npc sprite you want.

Thanks for the reply Emistry. Awesome as always.

I tried to add the campfire to a new rathena. It did not work for me. No errors on recompiling. Also added the functions and itemdb changes.
To no avail, when i click the matchstick, does not do anything.

Any thoughts where i went wrong?

  • Upvote 1

Share this post


Link to post
Share on other sites
Posted (edited)

Error in new rAthena:

In file included from script.cpp:24074:
../custom/script.inc: In function 'int buildin_duplicatenpc(script_state*)':
../custom/script.inc:86:11: warning: 'char* strncat(char*, const char*, size_t)' specified bound 1 equals source length [-Wstringop-overflow=]
    strncat(new_npc_name, "#", 1);
    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
../custom/script.inc:87:11: warning: 'char* strncat(char*, const char*, size_t)' specified bound depends on the length of the source argument [-Wstringop-overflow=]
    strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));
    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cannot use Campfire function in the newest rAthena /sob item won't do anything (It worked perfectly for me before updating rAthena).

Edited by OscarScorp

Share this post


Link to post
Share on other sites
4 hours ago, OscarScorp said:

Error in new rAthena:

In file included from script.cpp:24074:
../custom/script.inc: In function 'int buildin_duplicatenpc(script_state*)':
../custom/script.inc:86:11: warning: 'char* strncat(char*, const char*, size_t)' specified bound 1 equals source length [-Wstringop-overflow=]
    strncat(new_npc_name, "#", 1);
    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
../custom/script.inc:87:11: warning: 'char* strncat(char*, const char*, size_t)' specified bound depends on the length of the source argument [-Wstringop-overflow=]
    strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));
    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cannot use Campfire function in the newest rAthena /sob item won't do anything (It worked perfectly for me before updating rAthena).

That is what i've figured. Maybe you will need an rAthena that is at least back November of 2018

 

Share this post


Link to post
Share on other sites
On 4/2/2019 at 11:22 PM, Dev G Inc said:

That is what i've figured. Maybe you will need an rAthena that is at least back November of 2018

 

Wait, I got mine working. I... didn't do anything, it just started working.
Test your items:

50007,Campfire,Campfire,0,200,50,250,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc("func_CreateCampFire", 4, 40, 1); },{},{} //<range>, <duration>, <heal_rate>;
902,Tree_Root,Tree Root,0,12,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc("func_UpdateCampFire", 0, 2, 0); },{},{} //Modified item, now usable.

Revise the code provided by Emistry, or even if you need to, re-do the whole instalation process.

Share this post


Link to post
Share on other sites
13 hours ago, OscarScorp said:

Wait, I got mine working. I... didn't do anything, it just started working.
Test your items:

50007,Campfire,Campfire,0,200,50,250,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc("func_CreateCampFire", 4, 40, 1); },{},{} //<range>, <duration>, <heal_rate>;
902,Tree_Root,Tree Root,0,12,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc("func_UpdateCampFire", 0, 2, 0); },{},{} //Modified item, now usable.

Revise the code provided by Emistry, or even if you need to, re-do the whole instalation process.

I will try and use what you have here, giving you feedback soon on this. 😄

Share this post


Link to post
Share on other sites
On 4/11/2019 at 11:10 AM, Dev G Inc said:

I will try and use what you have here, giving you feedback soon on this. 😄

Also revise the item can be used in any map. Check item_flag.txt or item_nouse.txt if your Campfire appears on any of them.
hope you get yours solved!

@Emistry, thank you again for this amazing script.
If it's not an issue, is it possible to add the feature of only heal if the user is Sitting?

Share this post


Link to post
Share on other sites
Posted (edited)
OnCampFireHeal:
	[email protected] = getd(sprintf(".%s_healrate", [email protected]$));
	[email protected] = getd(sprintf(".%s_range", [email protected]$));
	getmapxy([email protected]$, [email protected], [email protected], BL_NPC);
	addrid(4, 0, ([email protected] - [email protected]), ([email protected] - [email protected]), ([email protected] + [email protected]), ([email protected] + [email protected]));
	if (Sitting)
		percentheal [email protected], [email protected];
	end;

maybe ... add this part into the script.

 

then find 

areapercentheal([email protected]$, ([email protected] - [email protected]), ([email protected] - [email protected]), ([email protected] + [email protected]), ([email protected] + [email protected]), [email protected], [email protected]);

and replace with

donpcevent [email protected]$+"::OnCampFireHeal";

 

Edited by Emistry

Share this post


Link to post
Share on other sites
Posted (edited)

Hi @Emistry, how can I get a static Campfire without countdown timer in the central square of Prontera like a NPC, so that players can recharge their energy by standing by?

EDIT: I have make this simple script, correct me if you see error:

prontera,155,178,4	script	Campfire	10252,{
	dispbottom "This beautiful bonfire quickly regenerates the HP and SP to anyone nearby!";
	end;
OnInit:
OnTimer2000:
	initnpctimer;
//	areapercentheal "<mapname>",<x1>,<y1>,<x2>,<y2>,<%hp>,<%sp>;
	areapercentheal "prontera",151,174,159,182,5,5;
	end;
}

...but with this I can't duplicate it easy in other cities! -.-

Edited by CyberDevil

Share this post


Link to post
Share on other sites

Working as of rAthena June 2019 version.

What worked for me.

1. Installed the patch diff.
2. Installed the Script function.
3. Replaced the UNITTYPE variables of the scrip to BL.
4. Installed the item db with the exception of changing the wood match to item 12740.

Previously was not working for me on using the matchsticks for some reason. If you encounter any problems, try to use a different USABLE item.

Thumbs up to @Emistry. Never Fails to Deliver.

 

Just a wild question.
Is there a way to do the following?

1. Increase the radius of the campfire.
2. Detect if there are any other Campfires near.

Share this post


Link to post
Share on other sites
On 7/28/2019 at 12:38 PM, Dev G Inc said:

1. Increase the radius of the campfire.

set the value for range parameter

On 7/28/2019 at 12:38 PM, Dev G Inc said:

2. Detect if there are any other Campfires near.

maybe... 

On 8/20/2019 at 12:51 AM, coperation said:

this my problem 

fixed and wait the new download to be available again.

  • MVP 1

Share this post


Link to post
Share on other sites

Is it possible to either to disable the stacking heal effect of the campfire?

Share this post


Link to post
Share on other sites
Posted (edited)

bump  sry   new comment on down

14 hours ago, Emistry said:

set the value for range parameter

maybe... 

fixed and wait the new download to be available again.

 

3 hours ago, Dev G Inc said:

Is it possible to either to disable the stacking heal effect of the campfire?

player can stack more campfire nearly  and can regen 100% every 1 sec in time 😞

Edited by coperation

Share this post


Link to post
Share on other sites
6 hours ago, coperation said:

bump  sry   new comment on down

 

player can stack more campfire nearly  and can regen 100% every 1 sec in time 😞

True, that is why i am asking the script developer if it is possible to disable that since i dont have much knowledge on how to modify it. But for discussion sake, the campfire is meant for no heal, low rate servers that enjoys natural healing of players.

A really remarkable script indeed.

Share this post


Link to post
Share on other sites
On 8/24/2019 at 7:27 PM, Dev G Inc said:

True, that is why i am asking the script developer if it is possible to disable that since i dont have much knowledge on how to modify it. But for discussion sake, the campfire is meant for no heal, low rate servers that enjoys natural healing of players.

A really remarkable script indeed.

I have set regeneration rate. To 1-2% per second. :😆

Share this post


Link to post
Share on other sites

Hi, may I know what error is this?

And how to fix it?

 

Capture.PNG

Share this post


Link to post
Share on other sites

looks like a really nice script , just like tree of savior eh ?

definitely will try this later

-

as i've read , for the campfire healing stack problem , maybe you guys can just add item cooldown trunk/db/item_delay.txt so the player cant stack the campfire

edit : this is so dumb , i just woke up and write this lol , sorry

Edited by cherryeury
-

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...