diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 59c46641762..b3f564cf32c 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -2872,7 +2872,7 @@ Type is the type of object to search for: 0 - Character object 1 - NPC object 2 - Pet object - 3 - Monster object + 3 - Monster object -- See 'getunitdata' for monster. 4 - Homunculus object 5 - Mercenary object 6 - Elemental object @@ -2910,6 +2910,13 @@ Notice that NPC objects disabled with 'disablenpc' will still be located. --------------------------------------- +*mapid2name() + +Returns the map name of the given map ID. Returns an empty string if given +map ID doesn't exist. + +--------------------------------------- + *getgmlevel() This function will return the (GM) level associated with the player group to which @@ -7064,7 +7071,7 @@ Changing a homunculus or pet name will be permanent. --------------------------------------- *getunitdata ,; -*setsetdata ,,; +*setunitdata ,,; This is used to get and set special data related to the unit. With getunitdata, the array given will be filled with the current data. In setunitdata @@ -7072,17 +7079,17 @@ the indexes in the array would be used to set that data on the unit. Parameters (indexes) for monsters are: - 0 - size (big, small, normal) 7 - y 14 - hair style 21 - weapon 28 - DEX - 1 - level 8 - speed 15 - hair color 22 - shield (again) 29 - LUK - 2 - HP 9 - mode 16 - head gear bottom 23 - looking dir 30 - for slave to copy master's mode - 3 - max HP 10 - special AI state 17 - head gear middle 24 - STR 31 - immune from attacks state - 4 - master AID 11 - SC option 18 - head gear top 25 - AGI - 5 - map index 12 - sex 19 - cloth color 26 - VIT - 6 - x 13 - class (Monster ID, Job ID) 20 - shield 27 - INT + 0 - size (big, small, normal) 7 - y 14 - hair style 21 - weapon 28 - LUK + 1 - level 8 - speed 15 - hair color 22 - looking dir 29 - for slave to copy master's mode + 2 - HP 9 - mode 16 - head gear bottom 23 - STR 30 - immune from attacks state + 3 - max HP 10 - special AI state 17 - head gear middle 24 - AGI + 4 - master AID 11 - SC option 18 - head gear top 25 - VIT + 5 - map ID 12 - sex 19 - cloth color 26 - INT + 6 - x 13 - class (Monster ID, Job ID) 20 - shield 27 - DEX Parameter (indexes) for homunculi are: - 0 - size (big, small, normal) 7 - map index 14 - canmove_tick 21 - immune from attacks state + 0 - size (big, small, normal) 7 - map ID 14 - canmove_tick 21 - immune from attacks state 1 - level 8 - x 15 - STR 2 - HP 9 - y 16 - AGI 3 - max HP 10 - hunger 17 - VIT @@ -7097,7 +7104,7 @@ Parameter (indexes) for pets are: 2 - HP 9 - intimacy 16 - INT 3 - max HP 10 - speed 17 - DEX 4 - master AID 11 - looking dir 18 - LUK - 5 - map index 12 - canmove_tick 19 - immune from attacks state + 5 - map ID 12 - canmove_tick 19 - immune from attacks state 6 - x 13 - STR Parameter (indexes) for mercenaries are: @@ -7106,7 +7113,7 @@ Parameter (indexes) for mercenaries are: 1 - HP 8 - life time 15 - INT 2 - max HP 9 - speed 16 - DEX 3 - master Character ID 10 - looking dir 17 - LUK - 4 - map index 11 - canmove_tick 18 - immune from attacks state + 4 - map ID 11 - canmove_tick 18 - immune from attacks state 5 - x 12 - STR 6 - y 13 - AGI @@ -7118,7 +7125,7 @@ Parameter (indexes) for elementals are: 3 - SP 10 - mode 17 - INT 4 - max SP 11 - speed 18 - DEX 5 - master Character ID 12 - looking dir 19 - LUK - 6 - map index 13 - canmove_tick 20 - immune from attacks state + 6 - map ID 13 - canmove_tick 20 - immune from attacks state Parameter (indexes) for NPCs are: @@ -7126,26 +7133,28 @@ Parameter (indexes) for NPCs are: 1 - level 8 - STR 2 - HP 9 - AGI 3 - max HP 10 - VIT - 4 - map index 11 - INT + 4 - map ID 11 - INT 5 - x 12 - DEX 6 - y 13 - LUK -*Note: For mode, see doc/mob_db_mode_list.txt +*Notes: For mode, see doc/mob_db_mode_list.txt + For map ID, this refers to the map_data index (from src/map/map.c), not the mapindex_db index (from src/common/mapindex.c) + For 'setunitdata', map name can also be passed in as a valid value instead of map ID Example: // Spawn some Porings and save the Game ID. // - Keep in mind, when the 'monster' script command is used, // - all the spawned monster GID's are stored in an array // - called $@mobid[]. - monster "prontera",123,42,"Poring",1002,10; + monster "prontera",149,190,"Poring",1002,10; .GID = $@mobid[9]; // Store and modify the 10th Poring spawned to make him stronger! // Save the strong Poring's mob data in the @por_arr[] variable. (@por_arr[1] being level, @por_arr[13] being class, etc.) + // With this data we can have the NPC display or manipulate it how we want. This does not have to be ran before 'setunitdata'. getunitdata .GID,@por_arr; - // Set the max HP of the Poring to 1000 and update the current HP to match. + // Set the max HP of the Poring to 1000 (current HP will also get updated to 1000). setunitdata .GID,3,1000; - setunitdata .GID,2,1000; --------------------------------------- \\ diff --git a/src/map/script.c b/src/map/script.c index 30be4b21f76..960f7997660 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13904,7 +13904,7 @@ BUILDIN_FUNC(getsavepoint) } /*========================================== - * Get position for char/npc/pet/mob objects. Added by Lorky + * Get position for char/NPC/pet/hom/merc/elem objects. Added by Lorky * * int getMapXY(MapName$,MapX,MapY,type,[CharName$]); * where type: @@ -13915,7 +13915,7 @@ BUILDIN_FUNC(getsavepoint) * 0 - Character coord * 1 - NPC coord * 2 - Pet coord - * 3 - Mob coord (not released) + * 3 - Mob coord (see 'getunitdata') * 4 - Homun coord * 5 - Mercenary coord * 6 - Elemental coord @@ -13986,7 +13986,7 @@ BUILDIN_FUNC(getmapxy) bl = &sd->pd->bl; break; case 3: //Get Mob Position - break; //Not supported? + break; //see 'getunitdata' case 4: //Get Homun Position if(script_hasdata(st,6)) sd=map_nick2sd(script_getstr(st,6)); @@ -14066,6 +14066,23 @@ BUILDIN_FUNC(getmapxy) return SCRIPT_CMD_SUCCESS; } +/// Returns the map name of given map ID. +/// +/// mapid2name ; +BUILDIN_FUNC(mapid2name) +{ + uint16 m = script_getnum(st, 2); + + if (m < 0 || m >= MAX_MAP_PER_SERVER) { + script_pushstr(st, ""); + return SCRIPT_CMD_FAILURE; + } + + script_pushstrcopy(st, map_mapid2mapname(m)); + + return SCRIPT_CMD_SUCCESS; +} + /*========================================== * Allows player to write NPC logs (i.e. Bank NPC, etc) [Lupus] *------------------------------------------*/ @@ -16252,16 +16269,15 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(19,md->vd->cloth_color); getunitdata_sub(20,md->vd->shield); getunitdata_sub(21,md->vd->weapon); - getunitdata_sub(22,md->vd->shield); - getunitdata_sub(23,md->ud.dir); - getunitdata_sub(24,md->status.str); - getunitdata_sub(25,md->status.agi); - getunitdata_sub(26,md->status.vit); - getunitdata_sub(27,md->status.int_); - getunitdata_sub(28,md->status.dex); - getunitdata_sub(29,md->status.luk); - getunitdata_sub(30,md->state.copy_master_mode); - getunitdata_sub(31,md->ud.immune_attack); + getunitdata_sub(22,md->ud.dir); + getunitdata_sub(23,md->status.str); + getunitdata_sub(24,md->status.agi); + getunitdata_sub(25,md->status.vit); + getunitdata_sub(26,md->status.int_); + getunitdata_sub(27,md->status.dex); + getunitdata_sub(28,md->status.luk); + getunitdata_sub(29,md->state.copy_master_mode); + getunitdata_sub(30,md->ud.immune_attack); break; case BL_HOM: @@ -16411,6 +16427,8 @@ BUILDIN_FUNC(getunitdata) BUILDIN_FUNC(setunitdata) { struct block_list* bl = NULL; + struct script_data* data; + const char *mapname = NULL; TBL_MOB* md = NULL; TBL_HOM* hd = NULL; TBL_MER* mc = NULL; @@ -16436,7 +16454,17 @@ BUILDIN_FUNC(setunitdata) } type = script_getnum(st, 3); - value = script_getnum(st, 4); + data = script_getdata(st, 4); + get_val(st, data); + + if (type == 5 && data_isstring(data)) + mapname = conv_str(st, data); + else if (data_isint(data)) + value = conv_num(st, data); + else { + ShowError("buildin_setunitdata: Invalid data type for argument #3 (%d).", data->type); + return SCRIPT_CMD_FAILURE; + } switch (bl->type) { case BL_MOB: @@ -16447,36 +16475,35 @@ BUILDIN_FUNC(setunitdata) switch (type) { case 0: md->status.size = (unsigned char)value; break; case 1: md->level = (unsigned short)value; break; - case 2: md->status.hp = (unsigned int)value; break; - case 3: md->status.max_hp = (unsigned int)value; break; + case 2: status_set_hp(bl, (unsigned int)value, 0); break; + case 3: status_set_maxhp(bl, (unsigned int)value, 0); break; case 4: md->master_id = value; break; - case 5: md->bl.m = (short)value; break; - case 6: md->bl.x = (short)value; break; - case 7: md->bl.y = (short)value; break; - case 8: md->status.speed = (unsigned short)value; break; - case 9: md->status.mode = (enum e_mode)value; break; + case 5: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 6: if (!unit_walktoxy(bl, (short)value, md->bl.y, 2)) unit_movepos(bl, (short)value, md->bl.y, 0, 0); break; + case 7: if (!unit_walktoxy(bl, md->bl.x, (short)value, 2)) unit_movepos(bl, md->bl.x, (short)value, 0, 0); break; + case 8: md->status.speed = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 9: md->status.mode = (enum e_mode)value; status_calc_bl(bl, SCB_MODE); break; case 10: md->special_state.ai = (enum mob_ai)value; break; case 11: md->sc.option = (unsigned short)value; break; case 12: md->vd->sex = (char)value; break; - case 13: md->vd->class_ = (unsigned short)value; break; - case 14: md->vd->hair_style = (unsigned short)value; break; - case 15: md->vd->hair_color = (unsigned short)value; break; - case 16: md->vd->head_bottom = (unsigned short)value; break; - case 17: md->vd->head_mid = (unsigned short)value; break; - case 18: md->vd->head_top = (unsigned short)value; break; - case 19: md->vd->cloth_color = (unsigned short)value; break; - case 20: md->vd->shield = (unsigned short)value; break; - case 21: md->vd->weapon = (unsigned short)value; break; - case 22: md->vd->shield = (unsigned short)value; break; - case 23: md->ud.dir = (unsigned char)value; break; - case 24: md->status.str = (unsigned int)value; break; - case 25: md->status.agi = (unsigned int)value; break; - case 26: md->status.vit = (unsigned int)value; break; - case 27: md->status.int_ = (unsigned int)value; break; - case 28: md->status.dex = (unsigned int)value; break; - case 29: md->status.luk = (unsigned int)value; break; - case 30: md->state.copy_master_mode = value > 0 ? 1 : 0; break; - case 31: md->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; + case 13: status_set_viewdata(bl, (unsigned short)value); break; + case 14: clif_changelook(bl, LOOK_HAIR, (unsigned short)value); break; + case 15: clif_changelook(bl, LOOK_HAIR_COLOR, (unsigned short)value); break; + case 16: clif_changelook(bl, LOOK_HEAD_BOTTOM, (unsigned short)value); break; + case 17: clif_changelook(bl, LOOK_HEAD_MID, (unsigned short)value); break; + case 18: clif_changelook(bl, LOOK_HEAD_TOP, (unsigned short)value); break; + case 19: clif_changelook(bl, LOOK_CLOTHES_COLOR, (unsigned short)value); break; + case 20: clif_changelook(bl, LOOK_SHIELD, (unsigned short)value); break; + case 21: clif_changelook(bl, LOOK_WEAPON, (unsigned short)value); break; + case 22: unit_setdir(bl, (uint8)value); break; + case 23: md->status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 24: md->status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 25: md->status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 26: md->status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 27: md->status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 28: md->status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 29: md->state.copy_master_mode = value > 0 ? 1 : 0; status_calc_bl(bl, SCB_MODE); break; + case 30: md->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_MOB.\n", type); return SCRIPT_CMD_FAILURE; @@ -16491,25 +16518,25 @@ BUILDIN_FUNC(setunitdata) switch (type) { case 0: hd->base_status.size = (unsigned char)value; break; case 1: hd->homunculus.level = (unsigned short)value; break; - case 2: hd->homunculus.hp = (unsigned int)value; break; - case 3: hd->homunculus.max_hp = (unsigned int)value; break; - case 4: hd->homunculus.sp = (unsigned int)value; break; - case 5: hd->homunculus.max_sp = (unsigned int)value; break; - case 6: hd->homunculus.char_id = (unsigned int)value; break; - case 7: hd->bl.m = (short)value; break; - case 8: hd->bl.x = (short)value; break; - case 9: hd->bl.y = (short)value; break; - case 10: hd->homunculus.hunger = (short)value; break; - case 11: hd->homunculus.intimacy = (unsigned int)value; break; - case 12: hd->base_status.speed = (unsigned short)value; break; - case 13: hd->ud.dir = (unsigned char)value; break; + case 2: status_set_hp(bl, (unsigned int)value, 0); break; + case 3: status_set_maxhp(bl, (unsigned int)value, 0); break; + case 4: status_set_sp(bl, (unsigned int)value, 0); break; + case 5: status_set_maxsp(bl, (unsigned int)value, 0); break; + case 6: hd->homunculus.char_id = (uint32)value; break; + case 7: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 8: if (!unit_walktoxy(bl, (short)value, hd->bl.y, 2)) unit_movepos(bl, (short)value, hd->bl.y, 0, 0); break; + case 9: if (!unit_walktoxy(bl, hd->bl.x, (short)value, 2)) unit_movepos(bl, hd->bl.x, (short)value, 0, 0); break; + case 10: hd->homunculus.hunger = (short)value; clif_send_homdata(map_charid2sd(hd->homunculus.char_id), SP_HUNGRY, hd->homunculus.hunger); break; + case 11: hom_increase_intimacy(hd, (unsigned int)value); clif_send_homdata(map_charid2sd(hd->homunculus.char_id), SP_INTIMATE, hd->homunculus.intimacy / 100); break; + case 12: hd->base_status.speed = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 13: unit_setdir(bl, (uint8)value); break; case 14: hd->ud.canmove_tick = value > 0 ? 1 : 0; break; - case 15: hd->base_status.str = (unsigned int)value; break; - case 16: hd->base_status.agi = (unsigned int)value; break; - case 17: hd->base_status.vit = (unsigned int)value; break; - case 18: hd->base_status.int_ = (unsigned int)value; break; - case 19: hd->base_status.dex = (unsigned int)value; break; - case 20: hd->base_status.luk = (unsigned int)value; break; + case 15: hd->base_status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 16: hd->base_status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 17: hd->base_status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 18: hd->base_status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 19: hd->base_status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 20: hd->base_status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; case 21: hd->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_HOM.\n", type); @@ -16525,23 +16552,23 @@ BUILDIN_FUNC(setunitdata) switch (type) { case 0: pd->status.size = (unsigned char)value; break; case 1: pd->pet.level = (unsigned short)value; break; - case 2: pd->status.hp = (unsigned int)value; break; - case 3: pd->status.max_hp = (unsigned int)value; break; + case 2: status_set_hp(bl, (unsigned int)value, 0); break; + case 3: status_set_maxhp(bl, (unsigned int)value, 0); break; case 4: pd->pet.account_id = (unsigned int)value; break; - case 5: pd->bl.m = (short)value; break; - case 6: pd->bl.x = (short)value; break; - case 7: pd->bl.y = (short)value; break; - case 8: pd->pet.hungry = (short)value; break; - case 9: pd->pet.intimate = (unsigned int)value; break; - case 10: pd->status.speed = (unsigned short)value; break; - case 11: pd->ud.dir = (unsigned char)value; break; + case 5: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 6: if (!unit_walktoxy(bl, (short)value, pd->bl.y, 2)) unit_movepos(bl, (short)value, md->bl.y, 0, 0); break; + case 7: if (!unit_walktoxy(bl, pd->bl.x, (short)value, 2)) unit_movepos(bl, pd->bl.x, (short)value, 0, 0); break; + case 8: pd->pet.hungry = (short)value; clif_send_petdata(map_id2sd(pd->pet.account_id), pd, 2, pd->pet.hungry); break; + case 9: pet_set_intimate(pd, (unsigned int)value); clif_send_petdata(map_id2sd(pd->pet.account_id), pd, 1, pd->pet.intimate); break; + case 10: pd->status.speed = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 11: unit_setdir(bl, (uint8)value); break; case 12: pd->ud.canmove_tick = value > 0 ? 1 : 0; break; - case 13: pd->status.str = (unsigned int)value; break; - case 14: pd->status.agi = (unsigned int)value; break; - case 15: pd->status.vit = (unsigned int)value; break; - case 16: pd->status.int_ = (unsigned int)value; break; - case 17: pd->status.dex = (unsigned int)value; break; - case 18: pd->status.luk = (unsigned int)value; break; + case 13: pd->status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 14: pd->status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 15: pd->status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 16: pd->status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 17: pd->status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 18: pd->status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; case 19: pd->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_PET.\n", type); @@ -16556,23 +16583,23 @@ BUILDIN_FUNC(setunitdata) } switch (type) { case 0: mc->base_status.size = (unsigned char)value; break; - case 1: mc->base_status.hp = (unsigned int)value; break; - case 2: mc->base_status.max_hp = (unsigned int)value; break; - case 3: mc->mercenary.char_id = (unsigned int)value; break; - case 4: mc->bl.m = (short)value; break; - case 5: mc->bl.x = (short)value; break; - case 6: mc->bl.y = (short)value; break; + case 1: status_set_hp(bl, (unsigned int)value, 0); break; + case 2: status_set_maxhp(bl, (unsigned int)value, 0); break; + case 3: mc->mercenary.char_id = (uint32)value; break; + case 4: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 5: if (!unit_walktoxy(bl, (short)value, mc->bl.y, 2)) unit_movepos(bl, (short)value, mc->bl.y, 0, 0); break; + case 6: if (!unit_walktoxy(bl, mc->bl.x, (short)value, 2)) unit_movepos(bl, mc->bl.x, (short)value, 0, 0); break; case 7: mc->mercenary.kill_count = (unsigned int)value; break; case 8: mc->mercenary.life_time = (unsigned int)value; break; - case 9: mc->base_status.speed = (unsigned short)value; break; - case 10: mc->ud.dir = (unsigned char)value; break; + case 9: mc->base_status.speed = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 10: unit_setdir(bl, (uint8)value); break; case 11: mc->ud.canmove_tick = value > 0 ? 1 : 0; break; - case 12: mc->base_status.str = (unsigned int)value; break; - case 13: mc->base_status.agi = (unsigned int)value; break; - case 14: mc->base_status.vit = (unsigned int)value; break; - case 15: mc->base_status.int_ = (unsigned int)value; break; - case 16: mc->base_status.dex = (unsigned int)value; break; - case 17: mc->base_status.luk = (unsigned int)value; break; + case 12: mc->base_status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 13: mc->base_status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 14: mc->base_status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 15: mc->base_status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 16: mc->base_status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 17: mc->base_status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; case 18: mc->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_MER.\n", type); @@ -16587,25 +16614,25 @@ BUILDIN_FUNC(setunitdata) } switch (type) { case 0: ed->base_status.size = (unsigned char)value; break; - case 1: ed->elemental.hp = (unsigned int)value; break; - case 2: ed->elemental.max_hp = (unsigned int)value; break; - case 3: ed->elemental.sp = (unsigned int)value; break; - case 4: ed->elemental.max_sp = (unsigned int)value; break; - case 5: ed->elemental.char_id = (unsigned int)value; break; - case 6: ed->bl.m = (short)value; break; - case 7: ed->bl.x = (short)value; break; - case 8: ed->bl.y = (short)value; break; + case 1: status_set_hp(bl, (unsigned int)value, 0); break; + case 2: status_set_maxhp(bl, (unsigned int)value, 0); break; + case 3: status_set_sp(bl, (unsigned int)value, 0); break; + case 4: status_set_maxsp(bl, (unsigned int)value, 0); break; + case 5: ed->elemental.char_id = (uint32)value; break; + case 6: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 7: if (!unit_walktoxy(bl, (short)value, ed->bl.y, 2)) unit_movepos(bl, (short)value, ed->bl.y, 0, 0); break; + case 8: if (!unit_walktoxy(bl, ed->bl.x, (short)value, 2)) unit_movepos(bl, ed->bl.x, (short)value, 0, 0); break; case 9: ed->elemental.life_time = (unsigned int)value; break; - case 10: ed->elemental.mode = (unsigned int)value; break; - case 11: ed->base_status.speed = (unsigned short)value; break; - case 12: ed->ud.dir = (unsigned char)value; break; + case 10: ed->elemental.mode = (unsigned int)value; status_calc_bl(bl, SCB_MODE); break; + case 11: ed->base_status.speed = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 12: unit_setdir(bl, (uint8)value); break; case 13: ed->ud.canmove_tick = value > 0 ? 1 : 0; break; - case 14: ed->base_status.str = (unsigned int)value; break; - case 15: ed->base_status.agi = (unsigned int)value; break; - case 16: ed->base_status.vit = (unsigned int)value; break; - case 17: ed->base_status.int_ = (unsigned int)value; break; - case 18: ed->base_status.dex = (unsigned int)value; break; - case 19: ed->base_status.luk = (unsigned int)value; break; + case 14: ed->base_status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 15: ed->base_status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 16: ed->base_status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 17: ed->base_status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 18: ed->base_status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 19: ed->base_status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; case 20: ed->ud.immune_attack = (bool)value > 0 ? 1 : 0; break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_ELEM.\n", type); @@ -16619,20 +16646,20 @@ BUILDIN_FUNC(setunitdata) return SCRIPT_CMD_FAILURE; } switch (type) { - case 0: nd->class_ = (unsigned int)value; break; + case 0: status_set_viewdata(bl, (unsigned short)value); break; case 1: nd->level = (unsigned int)value; break; - case 2: nd->status.hp = (unsigned int)value; break; - case 3: nd->status.max_hp = (unsigned int)value; break; - case 4: nd->bl.m = (short)value; break; - case 5: nd->bl.x = (short)value; break; - case 6: nd->bl.y = (short)value; break; - case 7: nd->ud.dir = (unsigned char)value; break; - case 8: nd->status.str = (unsigned int)value; break; - case 9: nd->status.agi = (unsigned int)value; break; - case 10: nd->status.vit = (unsigned int)value; break; - case 11: nd->status.int_ = (unsigned int)value; break; - case 12: nd->status.dex = (unsigned int)value; break; - case 13: nd->status.luk = (unsigned int)value; break; + case 2: status_set_hp(bl, (unsigned int)value, 0); break; + case 3: status_set_maxhp(bl, (unsigned int)value, 0); break; + case 4: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, 3); break; + case 5: if (!unit_walktoxy(bl, (short)value, nd->bl.y, 2)) unit_movepos(bl, (short)value, nd->bl.x, 0, 0); break; + case 6: if (!unit_walktoxy(bl, nd->bl.x, (short)value, 2)) unit_movepos(bl, nd->bl.x, (short)value, 0, 0); break; + case 7: unit_setdir(bl, (uint8)value); break; + case 8: nd->status.str = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 9: nd->status.agi = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 10: nd->status.vit = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 11: nd->status.int_ = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 12: nd->status.dex = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; + case 13: nd->status.luk = (unsigned short)value; status_calc_bl(bl, SCB_ALL); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_NPC.\n", type); return SCRIPT_CMD_FAILURE; @@ -16938,7 +16965,7 @@ BUILDIN_FUNC(unittalk) /// /// unitemote ,; /// -/// @see e_* in const.txt +/// @see e_* in db/const.txt BUILDIN_FUNC(unitemote) { int unit_id; @@ -17008,7 +17035,7 @@ BUILDIN_FUNC(unitskillusepos) return SCRIPT_CMD_SUCCESS; } -// <--- [zBuffer] List of mob control commands +// <--- [zBuffer] List of unit control commands /// Pauses the execution of the script, detaching the player /// @@ -20085,6 +20112,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] BUILDIN_DEF(npcstop,""), // [Valaris] BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] + BUILDIN_DEF(mapid2name,"i"), BUILDIN_DEF(checkoption1,"i"), BUILDIN_DEF(checkoption2,"i"), BUILDIN_DEF(guildgetexp,"i"), diff --git a/src/map/status.c b/src/map/status.c index aa31d65079c..15bdf7803c2 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1275,8 +1275,8 @@ static inline void status_cpy(struct status_data* a, const struct status_data* b /** * Sets HP to a given value - * Will always succeed (overrides heal impedement statuses) but can't kill an object - * @param bl: Object whose HP will be set [PC|MOB|HOM|MER|ELEM] + * Will always succeed (overrides heal impediment statuses) but can't kill an object + * @param bl: Object whose HP will be set [PC|MOB|HOM|MER|ELEM|NPC] * @param hp: What the HP is to be set as * @param flag: Used in case final value is higher than current * Use 2 to display healing effect @@ -1297,6 +1297,32 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag) return status_zap(bl, status->hp - hp, 0); } +/** + * Sets Max HP to a given value + * @param bl: Object whose Max HP will be set [PC|MOB|HOM|MER|ELEM|NPC] + * @param maxhp: What the Max HP is to be set as + * @param flag: Used in case final value is higher than current + * Use 2 to display healing effect + * @return heal or zapped HP if valid + */ +int status_set_maxhp(struct block_list *bl, unsigned int maxhp, int flag) +{ + struct status_data *status; + if (maxhp < 1) return 0; + status = status_get_status_data(bl); + if (status == &dummy_status) + return 0; + + if (maxhp == status->max_hp) return 0; + if (maxhp > status->max_hp) { + status_heal(bl, maxhp - status->max_hp, 0, 1|flag); + } else + status_zap(bl, status->max_hp - maxhp, 0); + + status->max_hp = maxhp; + return maxhp; +} + /** * Sets SP to a given value * @param bl: Object whose SP will be set [PC|HOM|MER|ELEM] @@ -1320,6 +1346,32 @@ int status_set_sp(struct block_list *bl, unsigned int sp, int flag) return status_zap(bl, 0, status->sp - sp); } +/** + * Sets Max SP to a given value + * @param bl: Object whose Max SP will be set [PC|HOM|MER|ELEM] + * @param maxsp: What the Max SP is to be set as + * @param flag: Used in case final value is higher than current + * Use 2 to display healing effect + * @return heal or zapped HP if valid + */ +int status_set_maxsp(struct block_list *bl, unsigned int maxsp, int flag) +{ + struct status_data *status; + if (maxsp < 1) return 0; + status = status_get_status_data(bl); + if (status == &dummy_status) + return 0; + + if (maxsp == status->max_sp) return 0; + if (maxsp > status->max_sp) { + status_heal(bl, maxsp - status->max_sp, 0, 1|flag); + } else + status_zap(bl, status->max_sp - maxsp, 0); + + status->max_sp = maxsp; + return maxsp; +} + /** * Takes HP/SP from an Object * @param bl: Object who will have HP/SP taken [PC|MOB|HOM|MER|ELEM] diff --git a/src/map/status.h b/src/map/status.h index c8968564540..d3fabb17201 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2003,7 +2003,9 @@ int status_percent_change(struct block_list *src, struct block_list *target, int #define status_kill(bl) status_percent_damage(NULL, bl, 100, 0, true) //Used to set the hp/sp of an object to an absolute value (can't kill) int status_set_hp(struct block_list *bl, unsigned int hp, int flag); +int status_set_maxhp(struct block_list *bl, unsigned int hp, int flag); int status_set_sp(struct block_list *bl, unsigned int sp, int flag); +int status_set_maxsp(struct block_list *bl, unsigned int hp, int flag); int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag); int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp);