Jump to content

pan

Community Contributors
  • Content Count

    355
  • Joined

  • Last visited

  • Days Won

    13

Posts posted by pan


  1. Whoops I forgot to change the map name, sorry :x

    OnInit:	// Mvp ids	setarray $MVP_id[0],id1,id2,id3;	// Mvp maps NO GAT's!	setarray $MVP_maps$[0],"map1","map2","map3";	// Respawn time (HOURS)	setarray $MVP_tm[0],tm1,tm2,tm3;	initnpctimer;	// IT SHOULD FALL HERE!	OnTimer3600: // After a hour		for( set .@i,0; .@i < getarraysize($MVP_id); set .@i, .@i+1 )		{			set .@time, $MVP_tm[.@i]*3600; // Conversion to seconds so we can use gettimetick			if( ($MVP_last_respawn[.@i] + $MVP_tm[.@i]) > gettimetick(2) )				continue; // Time has yet to pass			monster $MVP_maps$[.@i],0,0,"--ja--",$MVP_id[.@i],1;			// Defines last respawn			set $MVP_last_respawn[.@i], gettimetick(2);		}		setnpctimer 0;		end;
    Don't forget to delete the other spawns of those MVPS, otherwise this will just spawn other mob. Also this "mvp timer" continues to tick even if your server is off.

  2. I'm looking for the solution the whole day, but it seems there's none. Anyone?

    You could spawn mvps manually and create a global variable for each one of them containing the time of the last spawn...

    Something like:

    OnInit:	// Mvp ids	setarray $MVP_id[0],id1,id2,id3;	// Mvp maps NO GAT's!	setarray $MVP_maps$[0],"map1","map2","map3";	// Respawn time (HOURS)	setarray $MVP_tm[0],tm1,tm2,tm3;	initnpctimer;	// IT SHOULD FALL HERE!	OnTimer3600: // After a hour		for( set .@i,0; .@i < getarraysize($MVP_id); set .@i, .@i+1 )		{			set .@time, $MVP_tm[.@i]*3600; // Conversion to seconds so we can use gettimetick			if( ($MVP_last_respawn[.@i] + $MVP_tm[.@i]) > gettimetick(2) )				continue; // Time has yet to pass			monster "map",0,0,"--ja--",$MVP_id[.@i],1;			// Defines last respawn			set $MVP_last_respawn[.@i], gettimetick(2);		}		setnpctimer 0;		end;

  3. My point is, when using map_zone_db, you need to input each of every map that you want to affect the mapflag. In this case, its a server-wide modification using skillmodifier and skillduration features.

    As I stated in my previous post there is no need to input each map that is going to use a mapflag when using zones, as there is a zone that includes all maps.

    All you need to do is alter the "main" zone that's called "All", it should be the first one in your map_zone_db.conf

    name: "All"
    If you need to know how just read Ind's entry: http://herc.ws/board/topic/302-introducing-hercules-map-zone-database/

  4. There was an error in this snippet, I don't even know how this passed lol

    Here is the fix:

     

    Open src/map/skill.c and find:

    	// If linked, knights are able to use parrying with one handed swords (type 2)	if( require.weapon && !pc_check_weapontype(sd,require.weapon) && 	  ( skill_id == LK_PARRYING && !sd->sc.data[SC_SOULLINK] && !pc_check_weapontype(sd,2) ))	{		clif->skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);		return 0;	}
    Replace it with:
    	// If linked, knights are able to use parrying with one handed swords (type 2)	if( require.weapon && !pc_check_weapontype(sd,require.weapon) && 	  !( skill_id == LK_PARRYING && sd->sc.data[SC_SOULLINK] && pc_check_weapontype(sd,1<<2) ))	{		clif->skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);		return 0;	}
    Find (again):
    	if( require.weapon && !pc_check_weapontype(sd,require.weapon) && 	  ( skill_id == LK_PARRYING && !sd->sc.data[SC_SOULLINK] && !pc_check_weapontype(sd,2) ))	{		clif->skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);		return 0;	}
    Replace it with:
    	if( require.weapon && !pc_check_weapontype(sd,require.weapon) && 	  !( skill_id == LK_PARRYING && sd->sc.data[SC_SOULLINK] && pc_check_weapontype(sd,1<<2) ))	{		clif->skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);		return 0;	}
    Now it should work properly c: I'll update my original post (http://herc.ws/board/topic/3829-soul-link-modification/?p=24936) and change this.

    Thank you for reporting. Any errors or misbehaves just post here ok?


  5. I suggest the drop of those two mapflags since we got the power of map_zone_db.conf :P

    Mapflags are still being used in scripts through setmapflag and also in map_zone_db... I'm not sure whether there is any way to use zones via scripts.

     

    @Jezu

    It's not difficult to implement that, but there is no need to, just use map_zone_db.conf and add your mapflags to "All"

    http://herc.ws/board/topic/302-introducing-hercules-map-zone-database/


  6. This script doesn't use any query, so it won't update any of your tables... It uses this variable to store points:

    // Custom points, if needed: "<variable>","<name to display>"	setarray .Points$[0],"#CASHPOINTS","Cash Points";

  7.  

     

    Did you add your SC to db/const.txt? Also there is no need to add:

    StatusChangeFlagTable[SC_IGNOREDISPELL] |= SC_NONE;
    Maybe that's the line that's causing this misbehavior. I added this status without it and everything seemed to work just fine.

     

     

    Yes pan. That line was the problem. I was able to fixed mine using SC_ALL? BTW, dunno what is the purpose of this line..

     

     

     

     

    Did you add your SC to db/const.txt? Also there is no need to add:

    StatusChangeFlagTable[SC_IGNOREDISPELL] |= SC_NONE;
    Maybe that's the line that's causing this misbehavior. I added this status without it and everything seemed to work just fine.

     

     

    Yes pan. That line was the problem. I was able to fixed mine using SC_ALL? BTW, dunno what is the purpose of this line..

     

     

    SC_ALL is used for checking purposes, it must always be the last status change. It serves this purpose because of the way that enums work in C.

    Here is my diff file with all modifications needed in the source:

    diff --git a/src/map/skill.c b/src/map/skill.cindex 0df90a5..c10f89c 100644--- a/src/map/skill.c+++ b/src/map/skill.c@@ -6628,7 +6628,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin 				clif->skill_nodamage(src,bl,skill_id,skill_lv,1); 				if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) 					|| (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.-					|| rnd()%100 >= 50+10*skill_lv )+					|| rnd()%100 >= 50+10*skill_lv || (tsc && tsc->data[SC_IGNOREDISPELL])+					) 				{ 					if (sd) 						clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);diff --git a/src/map/status.h b/src/map/status.hindex d3148b4..ed2f182 100644--- a/src/map/status.h+++ b/src/map/status.h@@ -699,7 +699,8 @@ typedef enum sc_type { 	SC_OKTOBERFEST, 	SC_STRANGELIGHTS, 	SC_DECORATION_OF_MUSIC,-	++	SC_IGNOREDISPELL, 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; // Official status change ids, used to display status icons on the client.
    Regards

  8. I made this and tested real quick, if there are any errors just post and I'll correct them. Here is the diff file, just apply this changes: http://pastebin.com/gNApHdHj (you can do this manually as well)

     

    Hope I helped.

     

    EDIT:

    Don't forget to add in your conf/groups.conf this permission to groups that aren't going to be counted in the pvp rank:

    disable_pvp_rank: true

  9. Open src/map/skill.c and find:

    case ST_PRESERVE:
    Remove it

    Now find:

    clif->skill_nodamage(src,bl,skill_id,skill_lv,		sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));break;
    Add below:
    		case ST_PRESERVE:			if( sd )			{				if( sd->sc.count && sd->sc.data[SC_PRESERVE] )				{					status_change_end(bl, SC_PRESERVE, INVALID_TIMER);					clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);				}				else				{					clif->skill_nodamage(src,bl,skill_id,skill_lv,						sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));				}			}			break;
    Regards.

  10. Just by doing a quick look there's something strange going on, why are you using a pointer?

    int *isnear = 0;
    It looks as in pc_isnear_sub you are just using this pointer to point things that are in stack, so when this function returns it will point to something that can't really be accessed and will probably raise a SEGFAULT.
    if (isnear > 0){
    This line is just checking if there's an address set to '*isnear', not if the dereferenced value is bigger than 0.

    Also you are incrementing the pointer here not the dereferenced value:

    *isnear++;
    So you should do something like:
    int pc_isnear_sub(struct block_list *bl, va_list args){	int *isnear;	struct map_session_data *sd;	isnear = va_arg(args, int*);	sd = (struct map_session_data *)bl;	if( isnear == NULL || sd == NULL )		return 0;	if (sd->sc.data[SC_TRICKDEAD] ||		sd->sc.data[SC_HIDING] ||		sd->sc.data[SC_CLOAKING] ||		pc_isinvisible(sd) ||		sd->vd.class_ == INVISIBLE_CLASS ||		pc_isdead(sd)		)	{		return 0;	}	(*isnear)++;	return 1;}bool pc_isnear_mob( struct mob_data *md ){	int isnear;	isnear = 0;	map->foreachinrange((pc_isnear_sub), &md->bl, AREA_SIZE, BL_PC, &isnear);	return (isnear > 0)?true:false;}
    Regards.

  11. lol

    		if(    ( checkvending() == 2 && !.autotrade )	// Autotrade			&& ( checkidle() && !.idle )				// Idle			&& ( checkchatting() && !.chat )			// Chat			)			sleep2 1000;		set lrs_passed, lrs_passed+1;		set lrs_passed_total, lrs_passed_total+lrs_passed;
    where is the else statement ?

    this script means ... if the user is vending/idle/chatroom, the script will just delay execute by 1 sec ..

    but still continue to count the variables below

     

    the whole things below needs to be inside else { }

     

     

    Whoops, small mistake lol

    http://pastebin.com/QaGfva8H


  12. try not to use attachnpctimer unnecessary

    attachnpctimer I only use them in 1 scenario

    which use in botkiller script to kick players which doesn't answer in a certain time period

    means, only use in a npc dialog script

     

    because if this script already uses attachnpctimer,

    if there is other script use attachnpctimer again, the timer wouldn't run anymore

     

     

    for this kind of script, I rather use sleep2

    http://rathena.org/board/topic/90989-hourly-points-help/?p=238289

    Thank you, I wasn't aware of that.

    Well how can I make the reward goes to online players only, excluding @at. Since they may spam merchants and @at to get rewards.

    And can I make reward totally unable to change the owner including dropping, trading and vending.

    I added new configurations:
    // Account idle players? 1 - true; 0 - falseset .idle,1;// Account players using autotrade? 1 - true; 0 - falseset .autotrade,1;// Account players that are in chats? 1 - true; 0 - falseset .chat, 1;
    Set to false if you want that those players don't receive any prize.

    http://pastebin.com/aJV6beP8


  13.  

     

    As it is now it isn't compatible, most places that were changed have things that are only available in Hercules, if you need it to be compatible with eAthena just provide a revision number and I'll 'convert' this diff to it.

    Thank you! eAthena rev. 15234

    I think there is need to add some checks for flag in clif_sitting / clif_standing functions, right?

     

     

    There's no need to do that, all sitting requests pass trough ActionRequest_sub.

    Here is the new diff: http://pastebin.com/uMgV81Db

    Note that can_sit_anywhere is the minimum gm lvl to sit anywhere. Haven't tested this diff in-game, but there where no build errors.


  14.  

    I typically wouldn't place OnInit overhead, but due to the behaviour of the WARPNPC sprite, its script won't be run when clicked upon. Add this line above the OnInit label and see for yourself:

     

    message strcharinfo(0), "You touched me!";
     

    However, I do concede that it would be good habit to throw an end up there in any similar situation.

     

    Just tested, indeed WARPNPC has this behavior.


  15. As it is now it isn't compatible, most places that were changed have things that are only available in Hercules, if you need it to be compatible with eAthena just provide a revision number and I'll 'convert' this diff to it.


  16. I coded it for you:

    http://pastebin.com/fSPpQgBb

    Just do the changes that are depicted in this diff file, save and rebuild your map-server.

    I've also added a new group setting:

    can_sit_anywhere
    Just add it to all groups that can bypass 'nositting' restrictions.

     

    Oh, and only player controlled sitting is blocked (e.g. using insert), i.e. if a skill makes a player sit, it'll still do that even with the mapflag enabled, ok?

     

    Regards.


  17. Yeah, but OnPCLoadMapEvent runs through all maps that have a loadevent mapflag, which can cause high stress on the server when several players load those maps continuously. Understandably, there are some scenarios where a map isn't accessed by warp portal and OnPCLoadMapEvent would be appropriate; however, in this case the topic starter simply wanted a portal for quest-like purposes (and likely seamless integration). Sure, you'd have to disable existing warps that you would replace this "quest warp" with, but it would make sense that this tedium would be found in sensible applications, such as blocking off all warp-portal entrances into Morroc or something - and even so, this can be done by using duplicate to copy your script over without actually having to add another file/script.

     

    I see. Oh, and I think that after the header you should put an 'end;', if the script stays this way every time someone clicks the warp it will execute everything that's under OnInit's scope, that's unnecessary overhead. Thank you for your answer.


  18.  

    Why would it be? OnPCLoadMapEvent doesn't run until the player is already on the map. Your example would leave the player on the map itself after simply prompting them that they needed to have something to be there; then with that close, they'd walk happily off, confused as to why they were even told such a thing.

     

    Mhalicot's approach was on the right track, but I believe the topic starter would something more seamless. Here's my method:

     

    prontera,150,150,0	script	testwarp	WARPNPC,1,1,{	/*-----------------------------------------------------	Configuration	-----------------------------------------------------*/	OnInit:		.item_id = Jellopy;		.item_amount = 1;		.warp_map$ = "prontera";		.warp_x = 155;		.warp_y = 179;		end;			/*-----------------------------------------------------	Script	-----------------------------------------------------*/	OnTouch:		if (countitem(.item_id) < .item_amount) {			message strcharinfo(0), "You need "+ .item_amount +" "+ getitemname(.item_id) +" to access this warp.";		} else {			delitem .item_id, .item_amount;			warp .warp_map$, .warp_x, .warp_y;		}				end;}

     

    Ops, sorry, my mistake. It would be possible to use a warp afterwards, having to replace every warp that goes to a map would be a pain, and also every warp npc would have to mimic that invisible line that all warps have that triggers them.


  19. It's better to use the mapflag loadevent.

    Put this inside any script file:

    mapname	mapflag	loadevent
    Put this inside any npc:
    OnPCLoadMapEvent:	set @id, ITEMID;	set @quantity, QUANTITY;	if( strcharinfo(3) == MAPNAME )	{		if( countitem(@id) >= @quantity )			end;		mes "[Warp master]";		mes "You don't have the required item to enter this map!";		mes "Get "+@quantity+" "+getitemname(@id)+""+((@quantity > 1)?"s.":".");		close2;		warp "prontera",150,150;	}	end;
    EDIT:

    Corrected script


  20. http://herc.ws/board/topic/152-obtaining-hercules/

    http://herc.ws/wiki/Getting_Started

    http://herc.ws/board/topic/164-requested-links/

    The databases are still located inside 'db' but there are two sub-folders pre-re and re, the first is only activated when you are running an 'old times' server and the latter is active by default.

    Hercules is quite up to date, but it's not a priority, if you want to be up to date you should use rAthena instead, but Hercules uses less resources to run.


  21. All damage that's done by any skill passes through skill_attack that's in skill.c, open this file and search for:

    	damage = dmg.damage + dmg.damage2;	if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING ||		skill_id == CASH_BLESSING || skill_id == CASH_INCAGI ||		skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_PROPERTYUNDEAD] )		damage = 1;
    Just do any cap that you might need after this 'if'... Something like:
    	if( skill_id == MO_EXTREMITYFIST && damage > 9000 )		damage = 9000;
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.