Jump to content

Talis

Members
  • Posts

    7
  • Joined

  • Last visited

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1651 profile views

Talis's Achievements

Poring

Poring (1/15)

2

Reputation

1

Community Answers

  1. Could you try reverting those changes one at a time to determine exactly what change it was that introduced this error? Cause I feel that trying to debug it with the information you provided would be akin to finding a needle in a haystack.
  2. Talis

    set CELL_PK

    The relevant source block in battle.c: else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) { if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) ) return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else. else return 0; // You can't target anything out of your duel } If the only thing you replaced is else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) into else if(( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg&& map_flag_gvg(m))))||( cell_pk_check(t_bl, s_bl, m) == true )) Then it's no wonder that it's not working. Look at the line right below: if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) ) That translates to "If the target is a player AND targets duel_group matches mine" I would say just make a extra if / else, like so: case BL_PC: { struct map_session_data *sd = BL_CAST(BL_PC, s_bl); if( s_bl != t_bl ) { if( sd->state.killer ) { state |= BCT_ENEMY; // Can kill anything strip_enemy = 0; } else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) { if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) ) return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else. else return 0; // You can't target anything out of your duel } else if( cell_pk_check(t_bl, s_bl, m) == true ) { return (BCT_ENEMY&flag)?1:-1; } } if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM ) return 0; //If you don't belong to a guild, can't target emperium. if( t_bl->type != BL_PC ) state |= BCT_ENEMY; //Natural enemy. break; }
  3. You need a else between the first if and the second if. Right now, you check if the killed monster gives MVP EXP ( only true for MVPs ), then afterwards you separately check whether the mob has the boss flag ( true for both proper MVPs and mini bosses ). For MVP drop item 1, mini boss drop item 2, use: - script mvpkill -1,{ OnNPCKillEvent: if ( getmonsterinfo( killedrid, MOB_MVPEXP ) && rand(100) < 20 ) { if ( getcharid(1) ) { getpartymember getcharid(1), 1; getpartymember getcharid(1), 2; for ( .@i = 0; .@i < $@partymembercount; .@i++ ) { if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) ) { // what happens if someone in the party member is offline =/ .@partymemberaid[.@c] = $@partymemberaid[.@i]; .@c++; } } getitem 8400, 2, .@partymemberaid[ rand( .@c ) ]; announce "Player ["+ strcharinfo(0) +"] of ["+ strcharinfo(1) +"] party has killed "+ getmonsterinfo( killedrid, MOB_NAME ) +" at "+ strcharinfo(3), 0; } else { getitem 8400, 2; announce "Player ["+ strcharinfo(0) +"] has killed "+ getmonsterinfo( killedrid, MOB_NAME ) +" at "+ strcharinfo(3), 0; } } else if( getmonsterinfo(killedrid, 21) & 0x0020 && rand(100) < 20 ) { if ( getcharid(1) ) { getpartymember getcharid(1), 1; getpartymember getcharid(1), 2; for ( .@i = 0; .@i < $@partymembercount; .@i++ ) { if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) ) { // what happens if someone in the party member is offline =/ .@partymemberaid[.@c] = $@partymemberaid[.@i]; .@c++; } } getitem 8404, 1, .@partymemberaid[ rand( .@c ) ]; announce "You have received an item by killing "+ getmonsterinfo( killedrid, MOB_NAME ) +" .", bc_self; } else { getitem 8404, 1; announce "You have received an item by killing "+ getmonsterinfo( killedrid, MOB_NAME ) +" .", bc_self; } } end; } If you want ONLY mini bosses: - script mvpkill -1,{ OnNPCKillEvent: if ( !getmonsterinfo( killedrid, MOB_MVPEXP ) && getmonsterinfo(killedrid, 21) & 0x0020 && rand(100) < 20 ) { if ( getcharid(1) ) { getpartymember getcharid(1), 1; getpartymember getcharid(1), 2; for ( .@i = 0; .@i < $@partymembercount; .@i++ ) { if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) ) { // what happens if someone in the party member is offline =/ .@partymemberaid[.@c] = $@partymemberaid[.@i]; .@c++; } } getitem 8400, 2, .@partymemberaid[ rand( .@c ) ]; announce "Player ["+ strcharinfo(0) +"] of ["+ strcharinfo(1) +"] party has killed "+ getmonsterinfo( killedrid, MOB_NAME ) +" at "+ strcharinfo(3), 0; } else { getitem 8400, 2; announce "Player ["+ strcharinfo(0) +"] has killed "+ getmonsterinfo( killedrid, MOB_NAME ) +" at "+ strcharinfo(3), 0; } } end; }
  4. The only announcement / mention on the boards is here: http://rathena.org/board/topic/87083-julyaugust-digest/?hl=a4fdc72# This might not be 100% accurate since I'm new here and havn't worked with the system, but the gist is: Putting source mods directly into the .c files, such as script.c and atcommands.c is messy, because it can make revision updates troublesome - often leading to manually having to merge together your custom file and the new server revision file. The custom folder contains script.inc, script_def.inc, atcommand.inc and atcommand_def.inc. The main part of a script ( BUILDIN_FUNC(command) ) goes into custom/script.inc The definition of a script ( BUILDIN_DEF(command, parameters) ) goes into custom/script_def.inc The main part of a atcommand ( ACMD_FUNC(command) ) goes into custom/atcommand.inc The definition of a atcommand ( { "command", gmlevel,gmlevel, atcommand_command } ) goes into custom/atcommand_def.inc This keeps things organized, and your main eAthena source code clean, allowing for painless revision updates. Does that clear it up?
  5. Hey, I hope I won't be stepping on anyones toes, but I actually dev on a pretty customized version of eAthena, which doesn't have that functionality, else I would definitely make use of it. Looking at the example you linked, it should be really easy actually for people to make use of the custom folder functionality. I didn't provide diffs, just raw source, so the only thing that changes is where you copy & paste it to, right? Hm .. I might put up a new zip file soon where I mention that it can be put either in script.c or in script.inc So.. If you have the custom folder, throw it in the script.inc and script_def.inc instead of directly into script.c!
  6. File Name: Script command: Dynprompt File Submitter: Talis File Submitted: 08 Nov 2013 File Category: Source Modifications Content Author: Talis Works like prompt(), but lets you specify return values by adding a pipe symbol. Examples: dynprompt("Menu Entry"); Return Value: 1 @menu: 1 @menustr$: Menu Entry @menunum: 1 dynprompt("^EE0000Menu Entry^000000|Test"); Return Value: 1 @menu: 1 @menustr$: Test @menunum: 1 dynprompt("Shazam|5 Shazam"); Return Value: 5 @menu: 1 @menustr$: 5 Shazam @menunum: 5 Script example: // Dynprompt usage - Advanced example// Probably the best way to use thisfunction script dynprompt_sample3 { // The real power of dynprompt is that you can specify the return value for each menu element. // The return value is a atoi of the string following the pipe | - the full string can be accessed through @menustr$ // The atoi val can also be accessed through @menunum // If you want to use both number & string, the number has to come first else atoi won't work // Use the pipe character | to denote the return value - best to work with numbers, but strings work as well set .@menu$[0], "^009900Hello!^000000|1Hello"; set .@menu$[1], "^0000EEInfo~^000000|2Info"; set .@menu$[2], "^222222Test.^000000|3Test"; // This time we'll just add a element based on a condition if(.@somecondition) set .@menu$[3], "^EE0000- Admin -^000000|4Admin"; set .@menu$[4], "^990099G'bye^000000|5Bye"; // Lets implode & switch/case switch(dynprompt(implode(.@menu$, ":"))) { case 1: mes "Oh, Hello to you too!"; break; case 2: mes "You want info? How about the time?"; mes gettimestr("%Y-%m/%d %H:%M:%S",21); mes "Also, you selected option #" + @menu; // @menu still works break; case 3: mes "Debug info:"; mes "@menu is " + @menu; mes "@menustr$ is " + @menustr$; mes "@menunum is " + @menunum; break; case 4: mes "Wow, a admin!"; break; case 5: mes "Bye bye~"; break; case 255: // Cancel button mes "Hey, don't ignore me!!"; break; } close;} I havn't tested it yet in production, but so far I havn't been able to encounter any issues with it. Also, I do all my eAthena devving on a windows box so I can't guarantee that it'll work with linux. Performance of dynprompt is going to be naturally worse than prompt, select or menu, but it might perform equally well in a dynamic setting if you take into consideration the array looping usually required - but I have not yet done any benchmarking or anything, so don't take my word for it. ( and to be honest, being able to create super clean code using switch / case is worth a tiny performance hit for me ) I hope it will make your scripting less painful - it sure has for me! Click here to download this file
  7. Version 1.0

    33 downloads

    Works like prompt(), but lets you specify return values by adding a pipe symbol. Examples: dynprompt("Menu Entry"); Return Value: 1 @menu: 1 @menustr$: Menu Entry @menunum: 1 dynprompt("^EE0000Menu Entry^000000|Test"); Return Value: 1 @menu: 1 @menustr$: Test @menunum: 1 dynprompt("Shazam|5 Shazam"); Return Value: 5 @menu: 1 @menustr$: 5 Shazam @menunum: 5 Script example: // Dynprompt usage - Advanced example// Probably the best way to use thisfunction script dynprompt_sample3 { // The real power of dynprompt is that you can specify the return value for each menu element. // The return value is a atoi of the string following the pipe | - the full string can be accessed through @menustr$ // The atoi val can also be accessed through @menunum // If you want to use both number & string, the number has to come first else atoi won't work // Use the pipe character | to denote the return value - best to work with numbers, but strings work as well set .@menu$[0], "^009900Hello!^000000|1Hello"; set .@menu$[1], "^0000EEInfo~^000000|2Info"; set .@menu$[2], "^222222Test.^000000|3Test"; // This time we'll just add a element based on a condition if(.@somecondition) set .@menu$[3], "^EE0000- Admin -^000000|4Admin"; set .@menu$[4], "^990099G'bye^000000|5Bye"; // Lets implode & switch/case switch(dynprompt(implode(.@menu$, ":"))) { case 1: mes "Oh, Hello to you too!"; break; case 2: mes "You want info? How about the time?"; mes gettimestr("%Y-%m/%d %H:%M:%S",21); mes "Also, you selected option #" + @menu; // @menu still works break; case 3: mes "Debug info:"; mes "@menu is " + @menu; mes "@menustr$ is " + @menustr$; mes "@menunum is " + @menunum; break; case 4: mes "Wow, a admin!"; break; case 5: mes "Bye bye~"; break; case 255: // Cancel button mes "Hey, don't ignore me!!"; break; } close;} I havn't tested it yet in production, but so far I havn't been able to encounter any issues with it. Also, I do all my eAthena devving on a windows box so I can't guarantee that it'll work with linux. Performance of dynprompt is going to be naturally worse than prompt, select or menu, but it might perform equally well in a dynamic setting if you take into consideration the array looping usually required - but I have not yet done any benchmarking or anything, so don't take my word for it. ( and to be honest, being able to create super clean code using switch / case is worth a tiny performance hit for me ) I hope it will make your scripting less painful - it sure has for me!
    Free
×
×
  • Create New...