diff options
author | momacabu <momacabu@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-12-27 03:49:29 +0000 |
---|---|---|
committer | momacabu <momacabu@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-12-27 03:49:29 +0000 |
commit | f4867954028b6c7b4d37c9860696578b27d6dbd1 (patch) | |
tree | 64fb6aff134126f9eef4af54232dbb1cd0424b10 | |
parent | eb2af623ae935795182e062375094e458ead1dc5 (diff) | |
download | hercules-f4867954028b6c7b4d37c9860696578b27d6dbd1.tar.gz hercules-f4867954028b6c7b4d37c9860696578b27d6dbd1.tar.bz2 hercules-f4867954028b6c7b4d37c9860696578b27d6dbd1.tar.xz hercules-f4867954028b6c7b4d37c9860696578b27d6dbd1.zip |
* Implemented `useskilltopc' (tid:74685), and now if desired npcs can carry status such as str, atk, def, etc and level.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@17048 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | src/map/npc.h | 4 | ||||
-rw-r--r-- | src/map/script.c | 60 | ||||
-rw-r--r-- | src/map/status.c | 38 | ||||
-rw-r--r-- | src/map/status.h | 1 |
4 files changed, 97 insertions, 6 deletions
diff --git a/src/map/npc.h b/src/map/npc.h index 0379ae634..041adb7b6 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -39,6 +39,10 @@ struct npc_data { unsigned size : 2; + struct status_data status; + unsigned int level; + unsigned int stat_point; + void* chatdb; // pointer to a npc_parse struct (see npc_chat.c) char* path;/* path dir */ enum npc_subtype subtype; diff --git a/src/map/script.c b/src/map/script.c index a02c33cf8..55f6d0283 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -17254,9 +17254,9 @@ BUILDIN_FUNC(cleanmap) map_foreachinmap(atcommand_cleanfloor_sub, m, BL_ITEM); } else { x0 = script_getnum(st, 3); - y0 = script_getnum(st, 4); - x1 = script_getnum(st, 5); - y1 = script_getnum(st, 6); + y0 = script_getnum(st, 4); + x1 = script_getnum(st, 5); + y1 = script_getnum(st, 6); if (x0 > 0 && y0 > 0 && x1 > 0 && y1 > 0) { map_foreachinarea(atcommand_cleanfloor_sub, m, x0, y0, x1, y1, BL_ITEM); } else { @@ -17267,7 +17267,54 @@ BUILDIN_FUNC(cleanmap) return 0; } +/* Cast a skill on the attached player. + * useskilltopc <skill_id>, <skill_level>, <stat_point>, <npc_level>; + * useskilltopc "<skill_name>", <skill_level>, <stat_point>, <npc_level>; */ +BUILDIN_FUNC(useskilltopc) +{ + unsigned int skill_id; + unsigned short skill_level; + unsigned int stat_point; + unsigned int npc_level; + struct npc_data *nd; + struct map_session_data *sd; + + skill_id = script_isstring(st, 2) ? skill_name2id(script_getstr(st, 2)) : script_getnum(st, 2); + skill_level = script_getnum(st, 3); + stat_point = script_getnum(st, 4); + npc_level = script_getnum(st, 5); + sd = script_rid2sd(st); + nd = (struct npc_data *)map_id2bl(sd->npc_id); + + if (stat_point > battle_config.max_third_parameter) { + ShowError("useskilltopc: stat point exceeded maximum of %d.\n",battle_config.max_third_parameter ); + return 1; + } + if (npc_level > MAX_LEVEL) { + ShowError("useskilltopc: level exceeded maximum of %d.\n", MAX_LEVEL); + return 1; + } + if (sd == NULL || nd == NULL) { //ain't possible, but I don't trust people. + return 1; + } + + nd->level = npc_level; + nd->stat_point = stat_point; + + if (!nd->status.hp) { + status_calc_npc(nd, true); + } else { + status_calc_npc(nd, false); + } + if (skill_get_inf(skill_id)&INF_GROUND_SKILL) { + unit_skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level); + } else { + unit_skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level); + } + + return 0; +} // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT @@ -17708,9 +17755,10 @@ struct script_function buildin_func[] = { BUILDIN_DEF(is_function,"s"), BUILDIN_DEF(get_revision,""), BUILDIN_DEF(freeloop,"i"), - BUILDIN_DEF(getrandgroupitem, "ii"), - BUILDIN_DEF(cleanmap, "s"), - BUILDIN_DEF2(cleanmap, "cleanarea", "siiii"), + BUILDIN_DEF(getrandgroupitem,"ii"), + BUILDIN_DEF(cleanmap,"s"), + BUILDIN_DEF2(cleanmap,"cleanarea","siiii"), + BUILDIN_DEF(useskilltopc,"viii"), /** * @commands (script based) **/ diff --git a/src/map/status.c b/src/map/status.c index de1dde6ae..d4af092ad 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -3225,6 +3225,40 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) { return 0; } +int status_calc_npc_(struct npc_data *nd, bool first) { + struct status_data *status = &nd->status; + + if (!nd) + return 0; + + if (first) { + status->hp = 1; + status->sp = 1; + status->max_hp = 1; + status->max_sp = 1; + + status->def_ele = ELE_NEUTRAL; + status->ele_lv = 1; + status->race = RC_DEMIHUMAN; + status->size = nd->size; + status->rhw.range = 1 + status->size; + status->mode = MD_CANMOVE|MD_CANATTACK; + status->speed = nd->speed; + } + + status->str = nd->stat_point; + status->agi = nd->stat_point; + status->vit = nd->stat_point; + status->int_= nd->stat_point; + status->dex = nd->stat_point; + status->luk = nd->stat_point; + + status_calc_misc(&nd->bl, status, nd->level); + status_cpy(&nd->status, status); + + return 0; +} + static unsigned short status_calc_str(struct block_list *,struct status_change *,int); static unsigned short status_calc_agi(struct block_list *,struct status_change *,int); static unsigned short status_calc_vit(struct block_list *,struct status_change *,int); @@ -3963,6 +3997,7 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first) case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break; case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break; case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break; + case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break; } } @@ -5739,6 +5774,7 @@ int status_get_lv(struct block_list *bl) { case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level; case BL_MER: return ((TBL_MER*)bl)->db->lv; case BL_ELEM: return ((TBL_ELEM*)bl)->db->lv; + case BL_NPC: return ((TBL_NPC*)bl)->level; } return 1; } @@ -5767,6 +5803,7 @@ struct status_data *status_get_status_data(struct block_list *bl) case BL_HOM: return &((TBL_HOM*)bl)->battle_status; case BL_MER: return &((TBL_MER*)bl)->battle_status; case BL_ELEM: return &((TBL_ELEM*)bl)->battle_status; + case BL_NPC: return &((TBL_NPC*)bl)->status; default: return &dummy_status; } @@ -5782,6 +5819,7 @@ struct status_data *status_get_base_status(struct block_list *bl) case BL_HOM: return &((TBL_HOM*)bl)->base_status; case BL_MER: return &((TBL_MER*)bl)->base_status; case BL_ELEM: return &((TBL_ELEM*)bl)->base_status; + case BL_NPC: return &((TBL_NPC*)bl)->status; default: return NULL; } diff --git a/src/map/status.h b/src/map/status.h index 1e9245af2..9e162faeb 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1786,6 +1786,7 @@ int status_change_clear_buffs(struct block_list* bl, int type); #define status_calc_homunculus(hd, first) status_calc_bl_(&(hd)->bl, SCB_ALL, first) #define status_calc_mercenary(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first) #define status_calc_elemental(ed, first) status_calc_bl_(&(ed)->bl, SCB_ALL, first) +#define status_calc_npc(nd, first) status_calc_bl_(&(nd)->bl, SCB_ALL, first) void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first); int status_calc_mob_(struct mob_data* md, bool first); |