Taekwon Mission (iRO mode or?)


As I’ve seen from iRO:

If your target is Goblin, any monster called “Goblin” will count toward the mission (All 5 “Goblin”s will count, but not Goblin Steamrider).

Many players from various servers running *athena forks get problems with their Taekwon. The problem arises when their Taekwon Mission target is a mob whose name is having multiple occurrences  in the mob database(Goblin, Kobold, Dimik,Venatu,etc). This mod gives you the option to make it work like iRO(Goblin only), or apply it to all mobs with the same name.

Ref: http://irowiki.org/classic/Taekwon_Mission

http://pastebin.com/mw7B2vuR

 

Enjoy!

New card restriction mode


I’ve made a new mod! As a player, It is annoying when you enter a map, and one of your cards is restricted from that map. The result is that your item gets unequipped.

The good news is…You don’t have to forcefully un-equip those anymore. We can simply turn their card effects off. An added bonus is that you can turn it on or off in the config.

// Allow to equip items with compunded cards
// that are restricted from that map
// 0: Disable
// 1: Enable
// 2: Enable w/ message. (– The card ‘%s’ will not have any effect on this map. (%s) –)
new_card_restriction_mode: 1

Let me know if you want to buy it 😀

Barter trade with an NPC using swapshop


First entry for 2013! Someone asked me if I could make a cash shop that barters with items. After a few hours, I came up with something that will serve you right. I didn’t have any problem during the preliminary testing, but it may have some un-ironed bugs. Using the same format as the cash shop + an additional field that accepts the id of the item that the npc will barter with, swapshop is way to go 😀

A picture video paints a thousand million words. (available in 720p, crappy though)

Contact me to avail this mod. 😀 Skype: christiangeraldsantos

PS/Offtopic: Buying this will help me get my dream phone!! Thanks /no1

Sendmail Scriptcommand


This mod will enable a lot of new possibilities in scripts. This is a scriptcommand I wanted when I still had a server. It can be used in Achievement Systems, WoE prizes, and other events. This is better than getitem because the recipient doesn’t need to be online.

Preview:

https://i0.wp.com/i47.tinypic.com/douypu.jpg

Description:

*sendmail <Recipient’s Char ID>,”<Sender’s Name>”,”<Title>”,”<Body>”,<zeny>,<item_id>,<amount>{,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>};

Uses the same functions as the default mail system, but this time, it is done via script. All item, recipent, message, and title assignment are done in the background. Enjoy this free release. 🙂

PS: This have not been used on a live server, if you discover a bug (or if there’s something wrong with my coding) let me know.  😀

Here’s the sample achievement script that I used:

What it does: It automatically sends a reward to anyone who will get to job level 9.

-<TAB>script<TAB>Mail Test<TAB>-1,{
<pre>OnPCJobLvUpEvent:
if(JobLevel != 9) end;
set .charid, getcharid(0);
set .sender$, "Achievement System";
set .title$, "Basic Skills";
set .itemid, 501;
set .itemamount, 50;
set .zeny, 1000;
set .body$, "You have successfully unlocked the achievement '"+.title$+"'. You have received "+.itemamount+" "+getitemname(.itemid)+"s and "+.zeny+" zennies.";
sendmail .charid,.sender$,.title$,.body$,.itemid,.itemamount,.zeny;
end;
}

DIFF LINK

Prevent Idle Leveling (via Homunculus)


Prevent Idle Leveling + more


Index: conf/battle/exp.conf
===================================================================
--- conf/battle/exp.conf (revision 16816)
+++ conf/battle/exp.conf (working copy)
@@ -89,3 +89,10 @@
 // If no, an equation will be used which preserves statpoints earned/lost
 // through external means (ie: stat point buyers/sellers)
 use_statpoint_table: yes
+
+// Should the master and/or the homunculus stop receiving exp when idle? (uses party.conf's idle_no_share setting to determine the time to be considered idle) [clydelion]
+// 0 = Off
+// 1 = Master only
+// 2 = Homunculus only
+// 3 = Both
+prevent_idle_exp: 3
\ No newline at end of file
Index: conf/battle/homunc.conf
===================================================================
--- conf/battle/homunc.conf (revision 16816)
+++ conf/battle/homunc.conf (working copy)
@@ -43,3 +43,6 @@

 // Max level for Homunculus S
 homunculus_S_max_level: 150
+
+// Does the master gain job exp when a monster is killed by homunculus only? [clydelion]
+homunculus_job_exp: yes
\ No newline at end of file
Index: src/map/battle.c
===================================================================
--- src/map/battle.c (revision 16816)
+++ src/map/battle.c (working copy)
@@ -5738,6 +5738,8 @@
 { "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 },
 { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, },
 { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, },
+ { "homunculus_job_exp", &battle_config.homunculus_job_exp, 0, 0, 1, }, [clydelion]
+ { "prevent_idle_exp", &battle_config.prevent_idle_exp, 0, 0, 3, }, [clydelion]
 };
 #ifndef STATS_OPT_OUT
 /**
Index: src/map/battle.h
===================================================================
--- src/map/battle.h (revision 16816)
+++ src/map/battle.h (working copy)
@@ -480,6 +480,9 @@
 int atcommand_suggestions_enabled;
 int min_npc_vending_distance;
 int atcommand_mobinfo_type;
+
+ int homunculus_job_exp; [clydelion]
+ int prevent_idle_exp; [clydelion]
 } battle_config;

 void do_init_battle(void);
Index: src/map/homunculus.c
===================================================================
--- src/map/homunculus.c (revision 16816)
+++ src/map/homunculus.c (working copy)
@@ -435,6 +435,7 @@
 int merc_hom_gainexp(struct homun_data *hd,int exp)
 {
 int m_class;
+ TBL_PC * sd = hd->master; [clydelion]

 if(hd->homunculus.vaporize)
 return 1;
@@ -450,6 +451,8 @@
 hd->homunculus.exp = 0;
 return 0;
 }
+ if( battle_config.prevent_idle_exp > 1 && pc_isidle(sd) ) [clydelion]
+ return 0;

 hd->homunculus.exp += exp;

Index: src/map/mob.c
===================================================================
--- src/map/mob.c (revision 16816)
+++ src/map/mob.c (working copy)
@@ -2301,7 +2301,10 @@
 if(!md->db->mexp)
 party_renewal_exp_mod(&base_exp,&job_exp,tmpsd[i]->status.base_level,md->level);
 #endif
- pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
+ if(homkillonly && !battle_config.homunculus_job_exp) [clydelion]
+ pc_gainexp(tmpsd[i], &md->bl, base_exp, 0, false);
+ else
+ pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
 }
 }
 if(zeny) // zeny from mobs [Valaris]
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 16816)
+++ src/map/pc.c (working copy)
@@ -5557,7 +5557,7 @@
 if (sd->sc.data[SC_JEXPBOOST])
 bonus += sd->sc.data[SC_JEXPBOOST]->val1;

- *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX);
+ *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 0, UINT_MAX); [clydelion]

 return;
 }
@@ -5575,7 +5575,8 @@

 if(!battle_config.pvp_exp && map[sd->bl.m].flag.pvp) // [MouseJstr]
 return 0; // no exp on pvp maps
-
+ if ( ( battle_config.prevent_idle_exp == 1 || battle_config.prevent_idle_exp == 3 ) && pc_isidle(sd) && !quest) [clydelion]
+ return 0;
 if(sd->status.guild_id>0)
 base_exp-=guild_payexp(sd,base_exp);

Separate Instant Cast Setting per job


This diff will give you control over the instant cast setting per job (1st jobs, 2nd jobs, 3rd jobs)

1. Go over battle.c and diff as follows..

Index: src/map/battle.c
===================================================================
--- src/map/battle.c	(revision 16781)
+++ src/map/battle.c	(working copy)
@@ -5596,6 +5596,8 @@
 	{ "max_cloth_color",                    &battle_config.max_cloth_color,                 4,      0,      INT_MAX,        },
 	{ "pet_hair_style",                     &battle_config.pet_hair_style,                  100,    0,      INT_MAX,        },
 	{ "castrate_dex_scale",                 &battle_config.castrate_dex_scale,              150,    1,      INT_MAX,        },
+	{ "castrate_dex_scale_2",               &battle_config.castrate_dex_scale_2,            150,    1,      INT_MAX,        },
+	{ "castrate_dex_scale_3",               &battle_config.castrate_dex_scale_3,            150,    1,      INT_MAX,        },
 	{ "vcast_stat_scale",					&battle_config.vcast_stat_scale,			    530,    1,      INT_MAX,        },
 	{ "area_size",                          &battle_config.area_size,                       14,     0,      INT_MAX,        },
 	{ "zeny_from_mobs",                     &battle_config.zeny_from_mobs,                  0,      0,      1,              },

2. Define the new variables in battle.h

Index: src/map/battle.h
===================================================================
--- src/map/battle.h	(revision 16781)
+++ src/map/battle.h	(working copy)
@@ -345,6 +345,8 @@
 	int pet_hair_style; // added by [Skotlex]
 
 	int castrate_dex_scale; // added by [MouseJstr]
+	int castrate_dex_scale_2;
+	int castrate_dex_scale_3;
 	int area_size; // added by [MouseJstr]
 
 	int max_def, over_def_bonus; //added by [Skotlex]

3. Now, go over your skill.c to assign cast time for each.

Index: src/map/skill.c
===================================================================
--- src/map/skill.c	(revision 16781)
+++ src/map/skill.c	(working copy)
@@ -13356,10 +13356,22 @@
 
 		// calculate base cast time (reduced by dex)
 		if( !(skill_get_castnodex(skill_id, skill_lv)&1) ) {
-			int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
-			if( scale > 0 )	// not instant cast
-				time = time * scale / battle_config.castrate_dex_scale;
+			int scale = 0;
+			if(sd && sd->class_&JOBL_THIRD)
+				scale = battle_config.castrate_dex_scale_3 - status_get_dex(bl);
+			else if (sd && sd->class_&JOBL_2)
+				scale = battle_config.castrate_dex_scale_2 - status_get_dex(bl);
 			else
+				scale = battle_config.castrate_dex_scale - status_get_dex(bl);
+			if( scale > 0 ){	// not instant cast
+				if(sd && sd->class_&JOBL_THIRD)
+					time = time * scale / battle_config.castrate_dex_scale_3;
+				else if (sd && sd->class_&JOBL_2)
+					time = time * scale / battle_config.castrate_dex_scale_2;
+				else
+					time = time * scale / battle_config.castrate_dex_scale;
+			}
+			else
 				return 0;	// instant cast
 		}
 

4. and lastly, add it to the configuration (skill.conf)

Index: conf/battle/skill.conf
===================================================================
--- conf/battle/skill.conf	(revision 16781)
+++ conf/battle/skill.conf	(working copy)
@@ -38,7 +38,9 @@
 no_skill_delay: 2
 
 // At what dex does the cast time become zero (instacast)?
-castrate_dex_scale: 150
+castrate_dex_scale: 150 //1st class
+castrate_dex_scale_2: 150 //2nd class
+castrate_dex_scale_3: 150 //3rd class
 
 // How much (dex*2+int) does variable cast turns zero?
 vcast_stat_scale: 530

Bypass Trade Restriction via Trade Ticket


This modification allows you trade normally non-trade-able items using a custom trade ticket defined in  trade.h. The items are those defined in item_trade.txt

The currently set item is 501(Red Potion), it is recommended to change it to a custom non-droppable item.

Index: trade.c
 ===================================================================
 --- trade.c (revision 16496)
 +++ trade.c (working copy)
 @@ -316,6 +316,10 @@
 int trade_i, trade_weight;
 int src_lv, dst_lv;

+ //[clydelion]
 + int i,j = 0;
 + int ttcindex, ttc = 0;
 +
 nullpo_retv(sd);
 if( !sd->state.trading || sd->state.deal_locked > 0 )
 return; //Can't add stuff.
 @@ -343,7 +347,18 @@
 item = &sd->status.inventory[index];
 src_lv = pc_get_group_level(sd);
 dst_lv = pc_get_group_level(target_sd);
 - if( !itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade
 +
 + //[clydelion]
 + if( item->nameid == BYPASS_TRADE_TICKET )
 + return;
 + for( i = 0; i < MAX_INVENTORY; i++ ){
 + if( sd->status.inventory[i].nameid == BYPASS_TRADE_TICKET ){
 + j++;
 + ttc = sd->status.inventory[i].amount;
 + ttcindex = i;
 + }
 + }
 + if( (!itemdb_cantrade(item, src_lv, dst_lv) && !j && ttc < amount) && //Can't trade
 (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade
 {
 clif_displaymessage (sd->fd, msg_txt(260));
 @@ -373,6 +388,10 @@
 return;
 }

+ //[clydelion]
 + if(itemdb_cantrade(item, src_lv, dst_lv) == 0)
 + pc_delitem(sd,ttcindex,amount,0,0,LOG_TYPE_OTHER);
 +
 if( sd->deal.item[trade_i].index == index )
 { //The same item as before is being readjusted.
 if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount )
 @@ -448,6 +467,12 @@
 struct map_session_data *target_sd;
 int trade_i;

+ //[clydelion]
 + struct item item_tmp;
 + struct item item;
 + memset(&item_tmp,0,sizeof(item_tmp));
 + memset(&item,0,sizeof(item_tmp));
 + item_tmp.nameid=BYPASS_TRADE_TICKET;
 target_sd = map_id2sd(sd->trade_partner);

if(!sd->state.trading)
 @@ -464,6 +489,11 @@
 for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
 if (!sd->deal.item[trade_i].amount)
 continue;
 +
 + //[clydelion]
 + item = sd->status.inventory[sd->deal.item[trade_i].index];
 + if(itemdb_cantrade(&item, pc_get_group_level(sd), pc_get_group_level(target_sd)) == 0)
 + pc_additem(sd, &item_tmp, sd->deal.item[trade_i].amount,LOG_TYPE_OTHER);
 clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0);
 sd->deal.item[trade_i].index = 0;
 sd->deal.item[trade_i].amount = 0;
 @@ -484,6 +514,11 @@
 for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
 if (!target_sd->deal.item[trade_i].amount)
 continue;
 +
 + //[clydelion]
 + item = target_sd->status.inventory[target_sd->deal.item[trade_i].index];
 + if(itemdb_cantrade(&item, pc_get_group_level(target_sd), pc_get_group_level(sd)) == 0)
 + pc_additem(target_sd, &item_tmp, target_sd->deal.item[trade_i].amount,LOG_TYPE_OTHER);
 clif_additem(target_sd, target_sd->deal.item[trade_i].index, target_sd->deal.item[trade_i].amount, 0);
 target_sd->deal.item[trade_i].index = 0;
 target_sd->deal.item[trade_i].amount = 0;
 Index: trade.h
 ===================================================================
 --- trade.h (revision 16496)
 +++ trade.h (working copy)
 @@ -5,6 +5,9 @@
 #define _TRADE_H_

//#include "map.h"
 +
 +#define BYPASS_TRADE_TICKET 501 //[clydelion]
 +
 struct map_session_data;

void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd);