/src/map/pc.c
C | 9663 lines | 7776 code | 1063 blank | 824 comment | 2852 complexity | 32a4509e89109e4b9776d128ed008b02 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- // $Id: pc.c 101 2004-09-25 17:57:22Z Valaris $
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include "socket.h" // [Valaris]
- #include "timer.h"
- #include "db.h"
- #include "malloc.h"
- #include "nullpo.h"
- #include "strlib.h"
- #include "atcommand.h"
- #include "battle.h"
- #include "chat.h"
- #include "chrif.h"
- #include "clif.h"
- #include "guild.h"
- #include "intif.h"
- #include "itemdb.h"
- #include "map.h"
- #include "mob.h"
- #include "npc.h"
- #include "party.h"
- #include "pc.h"
- #include "script.h"
- #include "skill.h"
- #include "storage.h"
- #include "trade.h"
- #ifdef MEMWATCH
- #include "memwatch.h"
- #endif
- #define PVP_CALCRANK_INTERVAL 1000 // PVP順位計算の間隔
- //define it here, since the ifdef only occurs in this file
- #define USE_ASTRAL_SOUL_SKILL
- #define STATE_BLIND 0x10
- #ifdef USE_ASTRAL_SOUL_SKILL
- #define MAGIC_SKILL_THRESHOLD 200 // [fate] At this threshold, the Astral Soul skill kicks in
- #endif
- #define MAP_LOG_STATS(sd, suffix) \
- MAP_LOG_PC(sd, "STAT %d %d %d %d %d %d " suffix, \
- sd->status.str, sd->status.agi, sd->status.vit, sd->status.int_, sd->status.dex, sd->status.luk)
- #define MAP_LOG_XP(sd, suffix) \
- MAP_LOG_PC(sd, "XP %d %d JOB %d %d %d ZENY %d + %d " suffix, \
- sd->status.base_level, sd->status.base_exp, sd->status.job_level, sd->status.job_exp, sd->status.skill_point, sd->status.zeny, pc_readaccountreg(sd, "BankAccount"))
- #define MAP_LOG_MAGIC(sd, suffix) \
- MAP_LOG_PC(sd, "MAGIC %d %d %d %d %d %d EXP %d %d " suffix, \
- sd->status.skill[TMW_MAGIC].lv, \
- sd->status.skill[TMW_MAGIC_LIFE].lv, \
- sd->status.skill[TMW_MAGIC_WAR].lv, \
- sd->status.skill[TMW_MAGIC_TRANSMUTE].lv, \
- sd->status.skill[TMW_MAGIC_NATURE].lv, \
- sd->status.skill[TMW_MAGIC_ETHER].lv, \
- pc_readglobalreg(sd, "MAGIC_EXPERIENCE") & 0xffff, \
- (pc_readglobalreg(sd, "MAGIC_EXPERIENCE") >> 24) & 0xff)
- static int max_weight_base[MAX_PC_CLASS];
- static int hp_coefficient[MAX_PC_CLASS];
- static int hp_coefficient2[MAX_PC_CLASS];
- static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
- static int sp_coefficient[MAX_PC_CLASS];
- static int aspd_base[MAX_PC_CLASS][20];
- static char job_bonus[3][MAX_PC_CLASS][MAX_LEVEL];
- static int exp_table[14][MAX_LEVEL];
- static char statp[255][7];
- static struct
- {
- int id;
- int max;
- struct
- {
- short id, lv;
- } need[6];
- } skill_tree[3][MAX_PC_CLASS][100];
- static int atkmods[3][20]; // 武器ATKサイズ修正(size_fix.txt)
- static int refinebonus[5][3]; // 精?ボ?ナステ?ブル(refine_db.txt)
- static int percentrefinery[5][10]; // 精?成功率(refine_db.txt)
- static int dirx[8] = { 0, -1, -1, -1, 0, 1, 1, 1 };
- static int diry[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
- static unsigned int equip_pos[MAX_EQUIP_SIZE] =
- { 0x0080, 0x0008, 0x0040, 0x0004, 0x0001, 0x0200, 0x0100, 0x0010, 0x0020,
- 0x0002, 0x8000, 0x0400, 0x0800
- };
- int pc_attack_timer (int tid, unsigned int tick, int id, int data);
- //static struct dbt *gm_account_db;
- static struct gm_account *gm_account = NULL;
- static int GM_num = 0;
- const int MAX_PLAYER_CLASS = 8;
- int pc_isGM (struct map_session_data *sd)
- {
- // struct gm_account *p;
- int i;
- nullpo_retr (0, sd);
- /* p = numdb_search(gm_account_db, sd->status.account_id);
- if (p == NULL)
- return 0;
- return p->level;*/
- for (i = 0; i < GM_num; i++)
- if (gm_account[i].account_id == sd->status.account_id)
- return gm_account[i].level;
- return 0;
- }
- int pc_iskiller (struct map_session_data *src,
- struct map_session_data *target)
- {
- nullpo_retr (0, src);
- if (src->bl.type != BL_PC)
- return 0;
- if (src->special_state.killer)
- return 1;
- nullpo_retr (0, target);
- if (target->bl.type != BL_PC)
- return 0;
- if (target->special_state.killable)
- return 1;
- return 0;
- }
- int pc_set_gm_level (int account_id, int level)
- {
- int i;
- for (i = 0; i < GM_num; i++)
- {
- if (account_id == gm_account[i].account_id)
- {
- gm_account[i].level = level;
- return 0;
- }
- }
- GM_num++;
- gm_account = realloc (gm_account, sizeof (struct gm_account) * GM_num);
- if (!gm_account)
- {
- printf("out of memory pc_set_gm_level\n");
- exit(1);
- }
- gm_account[GM_num - 1].account_id = account_id;
- gm_account[GM_num - 1].level = level;
- return 0;
- }
- int pc_getrefinebonus (int lv, int type)
- {
- if (lv >= 0 && lv < 5 && type >= 0 && type < 3)
- return refinebonus[lv][type];
- return 0;
- }
- static int distance (int x0, int y0, int x1, int y1)
- {
- int dx, dy;
- dx = abs (x0 - x1);
- dy = abs (y0 - y1);
- return dx > dy ? dx : dy;
- }
- static int pc_invincible_timer (int tid, unsigned int tick __attribute__ ((unused)),
- int id, int data __attribute__ ((unused)))
- {
- struct map_session_data *sd;
- if ((sd = (struct map_session_data *) map_id2sd (id)) == NULL
- || sd->bl.type != BL_PC)
- return 1;
- if (sd->invincible_timer != tid)
- {
- if (battle_config.error_log)
- printf ("invincible_timer %d != %d\n", sd->invincible_timer, tid);
- return 0;
- }
- sd->invincible_timer = -1;
- return 0;
- }
- int pc_setinvincibletimer (struct map_session_data *sd, int val)
- {
- nullpo_retr (0, sd);
- if (sd->invincible_timer != -1)
- delete_timer (sd->invincible_timer, pc_invincible_timer);
- sd->invincible_timer =
- add_timer (gettick () + val, pc_invincible_timer, sd->bl.id, 0);
- return 0;
- }
- int pc_delinvincibletimer (struct map_session_data *sd)
- {
- nullpo_retr (0, sd);
- if (sd->invincible_timer != -1)
- {
- delete_timer (sd->invincible_timer, pc_invincible_timer);
- sd->invincible_timer = -1;
- }
- return 0;
- }
- int pc_delattacktimer (struct map_session_data *sd)
- {
- nullpo_retr (0, sd);
- if (sd->attacktimer != -1)
- {
- delete_timer (sd->attacktimer, pc_attack_timer);
- sd->attacktimer = -1;
- }
- return 0;
- }
- static int pc_spiritball_timer (int tid, unsigned int tick __attribute__ ((unused)),
- int id, int data __attribute__ ((unused)))
- {
- struct map_session_data *sd;
- int i;
- if ((sd = (struct map_session_data *) map_id2sd (id)) == NULL
- || sd->bl.type != BL_PC)
- return 1;
- if (sd->spirit_timer[0] != tid)
- {
- if (battle_config.error_log)
- printf ("spirit_timer %d != %d\n", sd->spirit_timer[0], tid);
- return 0;
- }
- sd->spirit_timer[0] = -1;
- for (i = 1; i < sd->spiritball && i < MAX_SKILL_LEVEL; i++)
- {
- sd->spirit_timer[i - 1] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
- }
- sd->spiritball--;
- if (sd->spiritball < 0)
- sd->spiritball = 0;
- clif_spiritball (sd);
- return 0;
- }
- int pc_addspiritball (struct map_session_data *sd, int interval, int max)
- {
- nullpo_retr (0, sd);
- if (max > MAX_SKILL_LEVEL)
- max = MAX_SKILL_LEVEL;
- if (sd->spiritball < 0)
- sd->spiritball = 0;
- if (sd->spiritball >= max)
- {
- int i;
- if (sd->spirit_timer[0] != -1)
- {
- delete_timer (sd->spirit_timer[0], pc_spiritball_timer);
- sd->spirit_timer[0] = -1;
- }
- for (i = 1; i < max; i++)
- {
- sd->spirit_timer[i - 1] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
- }
- }
- else
- sd->spiritball++;
- if (sd->spiritball >= 1 && sd->spiritball <= MAX_SKILL_LEVEL)
- {
- sd->spirit_timer[sd->spiritball - 1] =
- add_timer (gettick () + interval, pc_spiritball_timer, sd->bl.id, 0);
- clif_spiritball (sd);
- }
- return 0;
- }
- int pc_delspiritball (struct map_session_data *sd, int count, int type)
- {
- int i;
- nullpo_retr (0, sd);
- if (sd->spiritball <= 0)
- {
- sd->spiritball = 0;
- return 0;
- }
- if (count > sd->spiritball)
- count = sd->spiritball;
- sd->spiritball -= count;
- if (count > MAX_SKILL_LEVEL)
- count = MAX_SKILL_LEVEL;
- for (i = 0; i < count; i++)
- {
- if (sd->spirit_timer[i] != -1)
- {
- delete_timer (sd->spirit_timer[i], pc_spiritball_timer);
- sd->spirit_timer[i] = -1;
- }
- }
- for (i = count; i < MAX_SKILL_LEVEL; i++)
- {
- sd->spirit_timer[i - count] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
- }
- if (!type)
- clif_spiritball (sd);
- return 0;
- }
- int pc_setrestartvalue (struct map_session_data *sd, int type)
- {
- //?生や養子の場合の元の職業を算出する
- struct pc_base_job s_class;
- nullpo_retr (0, sd);
- s_class = pc_calc_base_job (sd->status.class);
- //-----------------------
- // 死亡した
- if (sd->special_state.restart_full_recover)
- { // オシリスカ?ド
- sd->status.hp = sd->status.max_hp;
- sd->status.sp = sd->status.max_sp;
- }
- else
- {
- if (s_class.job <= 5 && battle_config.restart_hp_rate == 0)
- { //ノビは半分回復
- sd->status.hp = (sd->status.max_hp) / 2;
- }
- else
- {
- if (battle_config.restart_hp_rate <= 0)
- sd->status.hp = 1;
- else
- {
- sd->status.hp =
- sd->status.max_hp * battle_config.restart_hp_rate / 100;
- if (sd->status.hp <= 0)
- sd->status.hp = 1;
- }
- }
- if (battle_config.restart_sp_rate > 0)
- {
- int sp = sd->status.max_sp * battle_config.restart_sp_rate / 100;
- if (sd->status.sp < sp)
- sd->status.sp = sp;
- }
- }
- if (type & 1)
- clif_updatestatus (sd, SP_HP);
- if (type & 1)
- clif_updatestatus (sd, SP_SP);
- /* removed exp penalty on spawn [Valaris] */
- if (type & 2 && sd->status.class > MAX_PLAYER_CLASS && battle_config.zeny_penalty > 0
- && !map[sd->bl.m].flag.nozenypenalty)
- {
- int zeny =
- (int) ((double) sd->status.zeny *
- (double) battle_config.zeny_penalty / 10000.);
- if (zeny < 1)
- zeny = 1;
- sd->status.zeny -= zeny;
- if (sd->status.zeny < 0)
- sd->status.zeny = 0;
- clif_updatestatus (sd, SP_ZENY);
- }
- sd->heal_xp = 0; // [Fate] Set gainable xp for healing this player to 0
- return 0;
- }
- /*==========================================
- * 自分をロックしているMOBの?を?える(foreachclient)
- *------------------------------------------
- */
- static int pc_counttargeted_sub (struct block_list *bl, va_list ap)
- {
- int id, *c, target_lv;
- struct block_list *src;
- nullpo_retr (0, bl);
- nullpo_retr (0, ap);
- id = va_arg (ap, int);
- nullpo_retr (0, c = va_arg (ap, int *));
- src = va_arg (ap, struct block_list *);
- target_lv = va_arg (ap, int);
- if (id == bl->id || (src && id == src->id))
- return 0;
- if (bl->type == BL_PC)
- {
- struct map_session_data *sd = (struct map_session_data *) bl;
- if (sd && sd->attacktarget == id && sd->attacktimer != -1
- && sd->attacktarget_lv >= target_lv)
- (*c)++;
- }
- else if (bl->type == BL_MOB)
- {
- struct mob_data *md = (struct mob_data *) bl;
- if (md && md->target_id == id && md->timer != -1
- && md->state.state == MS_ATTACK && md->target_lv >= target_lv)
- (*c)++;
- //printf("md->target_lv:%d, target_lv:%d\n",((struct mob_data *)bl)->target_lv,target_lv);
- }
- return 0;
- }
- int pc_counttargeted (struct map_session_data *sd, struct block_list *src,
- int target_lv)
- {
- int c = 0;
- nullpo_retr (0, sd);
- map_foreachinarea (pc_counttargeted_sub, sd->bl.m,
- sd->bl.x - AREA_SIZE, sd->bl.y - AREA_SIZE,
- sd->bl.x + AREA_SIZE, sd->bl.y + AREA_SIZE, 0,
- sd->bl.id, &c, src, target_lv);
- return c;
- }
- /*==========================================
- * ロ?カルプロトタイプ宣言 (必要な物のみ)
- *------------------------------------------
- */
- static int pc_walktoxy_sub (struct map_session_data *);
- /*==========================================
- * saveに必要なステ?タス修正を行なう
- *------------------------------------------
- */
- int pc_makesavestatus (struct map_session_data *sd)
- {
- nullpo_retr (0, sd);
- // 服の色は色?弊害が多いので保存?象にはしない
- if (!battle_config.save_clothcolor)
- sd->status.clothes_color = 0;
- // 死亡?態だったのでhpを1、位置をセ?ブ場所に?更
- if (pc_isdead (sd))
- {
- pc_setrestartvalue (sd, 0);
- memcpy (&sd->status.last_point, &sd->status.save_point,
- sizeof (sd->status.last_point));
- }
- else
- {
- memcpy (sd->status.last_point.map, sd->mapname, 24);
- sd->status.last_point.x = sd->bl.x;
- sd->status.last_point.y = sd->bl.y;
- }
- // セ?ブ禁止マップだったので指定位置に移動
- if (map[sd->bl.m].flag.nosave)
- {
- struct map_data *m = &map[sd->bl.m];
- if (strcmp (m->save.map, "SavePoint") == 0)
- memcpy (&sd->status.last_point, &sd->status.save_point,
- sizeof (sd->status.last_point));
- else
- memcpy (&sd->status.last_point, &m->save,
- sizeof (sd->status.last_point));
- }
- //マナ?ポイントがプラスだった場合0に
- if (battle_config.muting_players && sd->status.manner > 0)
- sd->status.manner = 0;
- return 0;
- }
- /*==========================================
- * 接?時の初期化
- *------------------------------------------
- */
- int pc_setnewpc (struct map_session_data *sd, int account_id, int char_id,
- int login_id1, int client_tick, int sex,
- int fd __attribute__ ((unused)))
- {
- nullpo_retr (0, sd);
- sd->bl.id = account_id;
- sd->char_id = char_id;
- sd->login_id1 = login_id1;
- sd->login_id2 = 0; // at this point, we can not know the value :(
- sd->client_tick = client_tick;
- sd->sex = sex;
- sd->state.auth = 0;
- sd->bl.type = BL_PC;
- sd->canact_tick = sd->canmove_tick = gettick ();
- sd->canlog_tick = gettick ();
- sd->state.waitingdisconnect = 0;
- return 0;
- }
- int pc_equippoint (struct map_session_data *sd, int n)
- {
- int ep = 0;
- //?生や養子の場合の元の職業を算出する
- struct pc_base_job s_class;
- nullpo_retr (0, sd);
- if (n < 0 || n >= MAX_INVENTORY || !sd->inventory_data[n])
- return 0;
- s_class = pc_calc_base_job (sd->status.class);
- ep = sd->inventory_data[n]->equip;
- if ((sd->inventory_data[n]->look == 1 || sd->inventory_data[n]->look == 2
- || sd->inventory_data[n]->look == 6) && (ep == 2
- &&
- (pc_checkskill (sd, AS_LEFT)
- > 0 || s_class.job == 12)))
- {
- return 34;
- }
- return ep;
- }
- int pc_setinventorydata (struct map_session_data *sd)
- {
- int i, id;
- nullpo_retr (0, sd);
- for (i = 0; i < MAX_INVENTORY; i++)
- {
- id = sd->status.inventory[i].nameid;
- sd->inventory_data[i] = itemdb_search (id);
- }
- return 0;
- }
- int pc_calcweapontype (struct map_session_data *sd)
- {
- nullpo_retr (0, sd);
- if (sd->weapontype1 != 0 && sd->weapontype2 == 0)
- sd->status.weapon = sd->weapontype1;
- if (sd->weapontype1 == 0 && sd->weapontype2 != 0) // 左手武器 Only
- sd->status.weapon = sd->weapontype2;
- else if (sd->weapontype1 == 1 && sd->weapontype2 == 1) // 双短剣
- sd->status.weapon = 0x11;
- else if (sd->weapontype1 == 2 && sd->weapontype2 == 2) // 双単手剣
- sd->status.weapon = 0x12;
- else if (sd->weapontype1 == 6 && sd->weapontype2 == 6) // 双単手斧
- sd->status.weapon = 0x13;
- else if ((sd->weapontype1 == 1 && sd->weapontype2 == 2) || (sd->weapontype1 == 2 && sd->weapontype2 == 1)) // 短剣 - 単手剣
- sd->status.weapon = 0x14;
- else if ((sd->weapontype1 == 1 && sd->weapontype2 == 6) || (sd->weapontype1 == 6 && sd->weapontype2 == 1)) // 短剣 - 斧
- sd->status.weapon = 0x15;
- else if ((sd->weapontype1 == 2 && sd->weapontype2 == 6) || (sd->weapontype1 == 6 && sd->weapontype2 == 2)) // 単手剣 - 斧
- sd->status.weapon = 0x16;
- else
- sd->status.weapon = sd->weapontype1;
- return 0;
- }
- int pc_setequipindex (struct map_session_data *sd)
- {
- int i, j;
- nullpo_retr (0, sd);
- for (i = 0; i < MAX_EQUIP_SIZE; i++)
- sd->equip_index[i] = -1;
- for (i = 0; i < MAX_INVENTORY; i++)
- {
- if (sd->status.inventory[i].nameid <= 0)
- continue;
- if (sd->status.inventory[i].equip)
- {
- for (j = 0; j < MAX_EQUIP_SIZE; j++)
- if (sd->status.inventory[i].equip & equip_pos[j])
- sd->equip_index[j] = i;
- if (sd->status.inventory[i].equip & 0x0002)
- {
- if (sd->inventory_data[i])
- sd->weapontype1 = sd->inventory_data[i]->look;
- else
- sd->weapontype1 = 0;
- }
- if (sd->status.inventory[i].equip & 0x0020)
- {
- if (sd->inventory_data[i])
- {
- if (sd->inventory_data[i]->type == 4)
- {
- if (sd->status.inventory[i].equip == 0x0020)
- sd->weapontype2 = sd->inventory_data[i]->look;
- else
- sd->weapontype2 = 0;
- }
- else
- sd->weapontype2 = 0;
- }
- else
- sd->weapontype2 = 0;
- }
- }
- }
- pc_calcweapontype (sd);
- return 0;
- }
- int pc_isequip (struct map_session_data *sd, int n)
- {
- struct item_data *item;
- struct status_change *sc_data;
- //転生や養子の場合の元の職業を算出する
- nullpo_retr (0, sd);
- if (n < 0 || n >= MAX_INVENTORY)
- return 0;
- item = sd->inventory_data[n];
- sc_data = battle_get_sc_data (&sd->bl);
- //s_class = pc_calc_base_job(sd->status.class);
- if (battle_config.gm_allequip > 0
- && pc_isGM (sd) >= battle_config.gm_allequip)
- return 1;
- if (item == NULL)
- return 0;
- if (item->sex != 2 && sd->status.sex != item->sex)
- return 0;
- if (item->elv > 0 && sd->status.base_level < item->elv)
- return 0;
- if (map[sd->bl.m].flag.pvp
- && (item->flag.no_equip == 1 || item->flag.no_equip == 3))
- return 0;
- if (map[sd->bl.m].flag.gvg
- && (item->flag.no_equip == 2 || item->flag.no_equip == 3))
- return 0;
- if (item->equip & 0x0002 && sc_data
- && sc_data[SC_STRIPWEAPON].timer != -1)
- return 0;
- if (item->equip & 0x0020 && sc_data
- && sc_data[SC_STRIPSHIELD].timer != -1)
- return 0;
- if (item->equip & 0x0010 && sc_data && sc_data[SC_STRIPARMOR].timer != -1)
- return 0;
- if (item->equip & 0x0100 && sc_data && sc_data[SC_STRIPHELM].timer != -1)
- return 0;
- return 1;
- }
- /*==========================================
- * Weapon Breaking [Valaris]
- *------------------------------------------
- */
- int pc_breakweapon (struct map_session_data *sd)
- {
- struct item_data *item;
- char output[255];
- int i;
- if (sd == NULL)
- return -1;
- if (sd->unbreakable >= MRAND (100))
- return 0;
- if (sd->sc_data && sd->sc_data[SC_CP_WEAPON].timer != -1)
- return 0;
- for (i = 0; i < MAX_INVENTORY; i++)
- {
- if (sd->status.inventory[i].equip
- && sd->status.inventory[i].equip & 0x0002
- && !sd->status.inventory[i].broken)
- {
- item = sd->inventory_data[i];
- if (!item)
- continue;
- sd->status.inventory[i].broken = 1;
- //pc_unequipitem(sd,i,0);
- if (sd->status.inventory[i].equip
- && sd->status.inventory[i].equip & 0x0002
- && sd->status.inventory[i].broken == 1)
- {
- sprintf (output, "%s has broken.", item->jname);
- clif_emotion (&sd->bl, 23);
- clif_displaymessage (sd->fd, output);
- clif_equiplist (sd);
- skill_status_change_start (&sd->bl, SC_BROKNWEAPON, 0, 0, 0,
- 0, 0, 0);
- }
- }
- if (sd->status.inventory[i].broken == 1)
- return 0;
- }
- return 0;
- }
- /*==========================================
- * Armor Breaking [Valaris]
- *------------------------------------------
- */
- int pc_breakarmor (struct map_session_data *sd)
- {
- struct item_data *item;
- char output[255];
- int i;
- if (sd == NULL)
- return -1;
- if (sd->unbreakable >= MRAND (100))
- return 0;
- if (sd->sc_data && sd->sc_data[SC_CP_ARMOR].timer != -1)
- return 0;
- for (i = 0; i < MAX_INVENTORY; i++)
- {
- if (sd->status.inventory[i].equip
- && sd->status.inventory[i].equip & 0x0010
- && !sd->status.inventory[i].broken)
- {
- item = sd->inventory_data[i];
- if (!item)
- continue;
- sd->status.inventory[i].broken = 1;
- //pc_unequipitem(sd,i,0);
- if (sd->status.inventory[i].equip
- && sd->status.inventory[i].equip & 0x0010
- && sd->status.inventory[i].broken == 1)
- {
- sprintf (output, "%s has broken.", item->jname);
- clif_emotion (&sd->bl, 23);
- clif_displaymessage (sd->fd, output);
- clif_equiplist (sd);
- skill_status_change_start (&sd->bl, SC_BROKNARMOR, 0, 0, 0, 0,
- 0, 0);
- }
- }
- if (sd->status.inventory[i].broken == 1)
- return 0;
- }
- return 0;
- }
- /*==========================================
- * session idに問題無し
- * char鯖から送られてきたステータスを設定
- *------------------------------------------
- */
- int pc_authok (int id, int login_id2, time_t connect_until_time,
- short tmw_version, struct mmo_charstatus *st)
- {
- struct map_session_data *sd = NULL;
- // struct party *p;
- // struct guild *g;
- int i;
- unsigned long tick = gettick ();
- struct sockaddr_in sai;
- socklen_t sa_len = sizeof(struct sockaddr);
- sd = map_id2sd (id);
- if (sd == NULL)
- return 1;
- sd->login_id2 = login_id2;
- sd->tmw_version = tmw_version;
- memcpy (&sd->status, st, sizeof (*st));
- if (sd->status.sex != sd->sex)
- {
- clif_authfail_fd (sd->fd, 0);
- return 1;
- }
- MAP_LOG_STATS (sd, "LOGIN");
- MAP_LOG_XP (sd, "LOGIN");
- MAP_LOG_MAGIC (sd, "LOGIN");
- memset (&sd->state, 0, sizeof (sd->state));
- // 基本的な初期化
- sd->state.connect_new = 1;
- sd->bl.prev = sd->bl.next = NULL;
- sd->weapontype1 = sd->weapontype2 = 0;
- sd->view_class = sd->status.class;
- sd->speed = DEFAULT_WALK_SPEED;
- sd->state.dead_sit = 0;
- sd->dir = 0;
- sd->head_dir = 0;
- sd->state.auth = 1;
- sd->walktimer = -1;
- sd->attacktimer = -1;
- sd->followtimer = -1; // [MouseJstr]
- sd->skilltimer = -1;
- sd->skillitem = -1;
- sd->skillitemlv = -1;
- sd->invincible_timer = -1;
- sd->sg_count = 0;
- sd->deal_locked = 0;
- sd->trade_partner = 0;
- sd->inchealhptick = 0;
- sd->inchealsptick = 0;
- sd->hp_sub = 0;
- sd->sp_sub = 0;
- sd->quick_regeneration_hp.amount = 0;
- sd->quick_regeneration_sp.amount = 0;
- sd->heal_xp = 0;
- sd->inchealspirithptick = 0;
- sd->inchealspiritsptick = 0;
- sd->canact_tick = tick;
- sd->canmove_tick = tick;
- sd->attackabletime = tick;
- /* We don't want players bypassing spell restrictions. [remoitnane] */
- sd->cast_tick = tick + pc_readglobalreg (sd, "MAGIC_CAST_TICK");
- sd->doridori_counter = 0;
- sd->spiritball = 0;
- for (i = 0; i < MAX_SKILL_LEVEL; i++)
- sd->spirit_timer[i] = -1;
- for (i = 0; i < MAX_SKILLTIMERSKILL; i++)
- sd->skilltimerskill[i].timer = -1;
- memset (&sd->dev, 0, sizeof (struct square));
- for (i = 0; i < 5; i++)
- {
- sd->dev.val1[i] = 0;
- sd->dev.val2[i] = 0;
- }
- // アカウント変数の送信要求
- intif_request_accountreg (sd);
- // アイテムチェック
- pc_setinventorydata (sd);
- pc_checkitem (sd);
- // ステータス異常の初期化
- for (i = 0; i < MAX_STATUSCHANGE; i++)
- {
- sd->sc_data[i].timer = -1;
- sd->sc_data[i].val1 = sd->sc_data[i].val2 = sd->sc_data[i].val3 =
- sd->sc_data[i].val4 = 0;
- }
- sd->sc_count = 0;
- if ((battle_config.atc_gmonly == 0 || pc_isGM (sd)) &&
- (pc_isGM (sd) >= get_atcommand_level (AtCommand_Hide)))
- sd->status.option &= (OPTION_MASK | OPTION_HIDE);
- else
- sd->status.option &= OPTION_MASK;
- // スキルユニット関係の初期化
- memset (sd->skillunit, 0, sizeof (sd->skillunit));
- memset (sd->skillunittick, 0, sizeof (sd->skillunittick));
- // init ignore list
- memset (sd->ignore, 0, sizeof (sd->ignore));
- // パーティー関係の初期化
- sd->party_sended = 0;
- sd->party_invite = 0;
- sd->party_x = -1;
- sd->party_y = -1;
- sd->party_hp = -1;
- // ギルド関係の初期化
- sd->guild_sended = 0;
- sd->guild_invite = 0;
- sd->guild_alliance = 0;
- // イベント関係の初期化
- memset (sd->eventqueue, 0, sizeof (sd->eventqueue));
- for (i = 0; i < MAX_EVENTTIMER; i++)
- sd->eventtimer[i] = -1;
- // 位置の設定
- pc_setpos (sd, sd->status.last_point.map, sd->status.last_point.x,
- sd->status.last_point.y, 0);
- // パーティ、ギルドデータの要求
- if (sd->status.party_id > 0
- && party_search (sd->status.party_id) == NULL)
- party_request_info (sd->status.party_id);
- if (sd->status.guild_id > 0
- && guild_search (sd->status.guild_id) == NULL)
- guild_request_info (sd->status.guild_id);
- // pvpの設定
- sd->pvp_rank = 0;
- sd->pvp_point = 0;
- sd->pvp_timer = -1;
- // 通知
- clif_authok (sd);
- map_addnickdb (sd);
- if (map_charid2nick (sd->status.char_id) == NULL)
- map_addchariddb (sd->status.char_id, sd->status.name);
- //スパノビ用死にカウンターのスクリプト変数からの読み出しとsdへのセット
- sd->die_counter = pc_readglobalreg (sd, "PC_DIE_COUNTER");
- if (night_flag == 1)
- {
- char tmpstr[1024];
- strcpy (tmpstr, msg_txt (500)); // Actually, it's the night...
- clif_wis_message (sd->fd, wisp_server_name, tmpstr,
- strlen (tmpstr) + 1);
- sd->opt2 |= STATE_BLIND;
- }
- // ステータス初期計算など
- pc_calcstatus (sd, 1);
- if (pc_isGM (sd))
- {
- printf
- ("Connection accepted: character '%s' (account: %d; GM level %d).\n",
- sd->status.name, sd->status.account_id, pc_isGM (sd));
- clif_updatestatus (sd, SP_GM);
- }
- else
- printf ("Connection accepted: Character '%s' (account: %d).\n",
- sd->status.name, sd->status.account_id);
- // Message of the Dayの送信
- {
- char buf[256];
- FILE *fp;
- if ((fp = fopen_ (motd_txt, "r")) != NULL)
- {
- while (fgets (buf, sizeof (buf) - 1, fp) != NULL)
- {
- int i;
- for (i = 0; buf[i]; i++)
- {
- if (buf[i] == '\r' || buf[i] == '\n')
- {
- buf[i] = 0;
- break;
- }
- }
- clif_displaymessage (sd->fd, buf);
- }
- fclose_ (fp);
- }
- }
- sd->auto_ban_info.in_progress = 0;
- // Initialize antispam vars
- sd->chat_reset_due = sd->chat_lines_in = sd->chat_total_repeats =
- sd->chat_repeat_reset_due = 0;
- sd->chat_lastmsg[0] = '\0';
- memset(sd->flood_rates, 0, sizeof(sd->flood_rates));
- sd->packet_flood_reset_due = sd->packet_flood_in = 0;
- // Obtain IP address (if they are still connected)
- if (!getpeername(sd->fd, (struct sockaddr *)&sai, &sa_len))
- sd->ip = sai.sin_addr.s_addr;
- // message of the limited time of the account
- if (connect_until_time != 0)
- { // don't display if it's unlimited or unknow value
- char tmpstr[1024];
- strftime (tmpstr, sizeof (tmpstr) - 1, msg_txt (501), gmtime (&connect_until_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
- clif_wis_message (sd->fd, wisp_server_name, tmpstr,
- strlen (tmpstr) + 1);
- }
- pc_calcstatus (sd, 1);
- return 0;
- }
- /*==========================================
- * session idに問題ありなので後始末
- *------------------------------------------
- */
- int pc_authfail (int id)
- {
- struct map_session_data *sd;
- sd = map_id2sd (id);
- if (sd == NULL)
- return 1;
- clif_authfail_fd (sd->fd, 0);
- return 0;
- }
- static int pc_calc_skillpoint (struct map_session_data *sd)
- {
- int i, skill_points = 0;
- nullpo_retr (0, sd);
- for (i = 0; i < skill_pool_skills_size; i++)
- {
- if (skill_pool_skills[i] < 0 || skill_pool_skills[i] >= MAX_SKILL)
- continue;
- int lv = sd->status.skill[skill_pool_skills[i]].lv;
- if (lv)
- skill_points += ((lv * (lv - 1)) >> 1) - 1;
- }
- return skill_points;
- }
- /*==========================================
- * 覚えられるスキルの計算
- *------------------------------------------
- */
- int pc_calc_skilltree (struct map_session_data *sd)
- {
- int i, id = 0;
- int c = 0, s = 0;
- //転生や養子の場合の元の職業を算出する
- struct pc_base_job s_class;
- nullpo_retr (0, sd);
- s_class = pc_calc_base_job (sd->status.class);
- c = s_class.job;
- s = (s_class.upper == 1) ? 1 : 0; //転生以外は通常のスキル?
- if ((battle_config.skillup_limit)
- && ((c >= 0 && c < 23) || (c >= 4001 && c < 4023)
- || (c >= 4023 && c < 4045)))
- {
- int skill_point = pc_calc_skillpoint (sd);
- if (skill_point < 9)
- c = 0;
- else if ((sd->status.skill_point >= sd->status.job_level
- && skill_point < 58) && ((c > 6 && c < 23) || (c > 4007
- && c < 4023)
- || (c > 4029 && c < 4045)))
- {
- switch (c)
- {
- case 7:
- case 14:
- c = 1;
- break;
- case 8:
- case 15:
- c = 4;
- break;
- case 9:
- case 16:
- c = 2;
- break;
- case 10:
- case 18:
- c = 5;
- break;
- case 11:
- case 19:
- case 20:
- c = 3;
- break;
- case 12:
- case 17:
- c = 6;
- break;
- case 4008:
- case 4015:
- c = 4002;
- break;
- case 4009:
- case 4016:
- c = 4005;
- break;
- case 4010:
- case 4017:
- c = 4003;
- break;
- case 4011:
- case 4019:
- c = 4006;
- break;
- case 4012:
- case 4020:
- case 4021:
- c = 4004;
- break;
- case 4013:
- case 4018:
- c = 4007;
- break;
- case 4030:
- case 4037:
- c = 4024;
- break;
- case 4031:
- case 4038:
- c = 4027;
- break;
- case 4032:
- case 4039:
- c = 4025;
- break;
- case 4033:
- case 4040:
- c = 4028;
- break;
- case 4034:
- case 4041:
- case 4042:
- c = 4026;
- break;
- case 4035:
- case 4043:
- c = 4029;
- break;
- default:
- break;
- }
- }
- }
- /*Comment this out for now, as we manage skills differently
- * for(i=0;i<MAX_SKILL;i++)
- * if (i < TMW_MAGIC || i > TMW_MAGIC_END){ // [Fate] This hack gets TMW magic working and persisted without bothering about the skill tree.
- * if (sd->status.skill[i].flag != 13) sd->status.skill[i].id=0;
- * if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、
- * sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本当のlvに
- * sd->status.skill[i].flag=0; // flagは0にしておく
- * }
- * }
- */
- if (battle_config.gm_allskill > 0
- && pc_isGM (sd) >= battle_config.gm_allskill)
- {
- // 全てのスキル
- for (i = 1; i < 158; i++)
- sd->status.skill[i].id = i;
- for (i = 210; i < 291; i++)
- sd->status.skill[i].id = i;
- for (i = 304; i < 337; i++)
- sd->status.skill[i].id = i;
- if (battle_config.enable_upper_class)
- { //confで無効でなければ読み込む
- for (i = 355; i < MAX_SKILL; i++)
- sd->status.skill[i].id = i;
- }
- }
- else
- {
- int flag;
- // 通常の計算
- do
- {
- flag = 0;
- for (i = 0; (id = skill_tree[s][c][i].id) > 0; i++)
- {
- int f = 1;
- if (!battle_config.skillfree)
- {
- int j;
- for (j = 0; j < 5; j++)
- {
- if (skill_tree[s][c][i].need[j].id &&
- pc_checkskill (sd,
- skill_tree[s][c][i].need[j].id) <
- skill_tree[s][c][i].need[j].lv)
- f = 0;
- }
- }
- if (f && sd->status.skill[id].id == 0)
- {
- sd->status.skill[id].id = id;
- flag = 1;
- }
- }
- }
- while (flag);
- }
- // if(battle_config.etc_log)
- // printf("calc skill_tree\n");
- return 0;
- }
- /*==========================================
- * 重量アイコンの確認
- *------------------------------------------
- */
- int pc_checkweighticon (struct map_session_data *sd)
- {
- int flag = 0;
- nullpo_retr (0, sd);
- if (sd->weight * 2 >= sd->max_weight
- && sd->sc_data[SC_FLYING_BACKPACK].timer == -1)
- flag = 1;
- if (sd->weight * 10 >= sd->max_weight * 9)
- flag = 2;
- if (flag == 1)
- {
- if (sd->sc_data[SC_WEIGHT50].timer == -1)
- skill_status_change_start (&sd->bl, SC_WEIGHT50, 0, 0, 0, 0, 0,
- 0);
- }
- else
- {
- skill_status_change_end (&sd->bl, SC_WEIGHT50, -1);
- }
- if (flag == 2)
- {
- if (sd->sc_data[SC_WEIGHT90].timer == -1)
- skill_status_change_start (&sd->bl, SC_WEIGHT90, 0, 0, 0, 0, 0,
- 0);
- }
- else
- {
- skill_status_change_end (&sd->bl, SC_WEIGHT90, -1);
- }
- return 0;
- }
- void pc_set_weapon_look (struct map_session_data *sd)
- {
- if (!sd)
- return;
- if (sd->attack_spell_override)
- clif_changelook (&sd->bl, LOOK_WEAPON,
- sd->attack_spell_look_override);
- else
- clif_changelook (&sd->bl, LOOK_WEAPON, sd->status.weapon);
- }
- /*==========================================
- * パラメータ計算
- * first==0の時、計算対象のパラメータが呼び出し前から
- * 変 化した場合自動でsendするが、
- * 能動的に変化させたパラメータは自前でsendするように
- *------------------------------------------
- */
- int pc_calcstatus (struct map_session_data *sd, int first)
- {
- int b_speed, b_max_hp, b_max_sp, b_hp, b_sp, b_weight, b_max_weight,
- b_paramb[6], b_parame[6], b_hit, b_flee;
- int b_aspd, b_watk, b_def, b_watk2, b_def2, b_flee2, b_critical,
- b_attackrange, b_matk1, b_matk2, b_mdef, b_mdef2, b_class;
- int b_base_atk;
- struct skill b_skill[MAX_SKILL];
- int i, bl, index;
- int skill, aspd_rate, wele, wele_, def_ele, refinedef = 0;
- int str, dstr, dex;
- struct pc_base_job s_class;
- nullpo_retr (0, sd);
- //転生や養子の場合の元の職業を算出する
- s_class = pc_calc_base_job (sd->status.class);
- b_speed = sd->speed;
- b_max_hp = sd->status.max_hp;
- b_max_sp = sd->status.max_sp;
- b_hp = sd->status.hp;
- b_sp = sd->status.sp;
- b_weight = sd->weight;
- b_max_weight = sd->max_weight;
- memcpy (b_paramb, &sd->paramb, sizeof (b_paramb));
- memcpy (b_parame, &sd->paramc, sizeof (b_parame));
- memcpy (b_skill, &sd->status.skill, sizeof (b_skill));
- b_hit = sd->hit;
- b_flee = sd->flee;
- b_aspd = sd->aspd;
- b_watk = sd->watk;
- b_def = sd->def;
- b_watk2 = sd->watk2;
- b_def2 = sd->def2;
- b_flee2 = sd->flee2;
- b_critical = sd->critical;
- b_attackrange = sd->attackrange;
- b_matk1 = sd->matk1;
- b_matk2 = sd->matk2;
- b_mdef = sd->mdef;
- b_mdef2 = sd->mdef2;
- b_class = sd->view_class;
- sd->view_class = sd->status.class;
- b_base_atk = sd->base_atk;
- pc_calc_skilltree (sd); // スキルツリーの計算
- sd->max_weight = max_weight_base[s_class.job] + sd->status.str * 300;
- if (first & 1)
- {
- sd->weight = 0;
- for (i = 0; i < MAX_INVENTORY; i++)
- {
- if (sd->status.inventory[i].nameid == 0
- || sd->inventory_data[i] == NULL)
- continue;
- sd->weight +=
- sd->inventory_data[i]->weight *
- sd->status.inventory[i].amount;
- }
- sd->cart_max_weight = battle_config.max_cart_weight;
- sd->cart_weight = 0;
- sd->cart_max_num = MAX_CART;
- sd->cart_num = 0;
- for (i = 0; i < MAX_CART; i++)
- {
- if (sd->status.cart[i].nameid == 0)
- continue;
- sd->cart_weight +=
- itemdb_weight (sd->status.cart[i].nameid) *
- sd->status.cart[i].amount;
- sd->cart_num++;
- }
- }
- memset (sd->paramb, 0, sizeof (sd->paramb));
- memset (sd->parame, 0, sizeof (sd->parame));
- sd->hit = 0;
- sd->flee = 0;
- sd->flee2 = 0;
- sd->critical = 0;
- sd->aspd = 0;
- sd->watk = 0;
- sd->def = 0;
- sd->mdef = 0;
- sd->watk2 = 0;
- sd->def2 = 0;
- sd->mdef2 = 0;
- sd->status.max_hp = 0;
- sd->status.max_sp = 0;
- sd->attackrange = 0;
- sd->attackrange_ = 0;
- sd->atk_ele = 0;
- sd->def_ele = 0;
- sd->star = 0;
- sd->overrefine = 0;
- sd->matk1 = 0;
- sd->matk2 = 0;
- sd->speed = DEFAULT_WALK_SPEED;
- sd->hprate = 100;
- sd->sprate = 100;
- sd->castrate = 100;
- sd->dsprate = 100;
- sd->base_atk = 0;
- sd->arrow_atk = 0;
- sd->arrow_ele = 0;
- sd->arrow_hit = 0;
- sd->arrow_range = 0;
- sd->nhealhp = sd->nhealsp = sd->nshealhp = sd->nshealsp = sd->nsshealhp =
- sd->nsshealsp = 0;
- memset (sd->addele, 0, sizeof (sd->addele));
- memset (sd->addrace, 0, sizeof (sd->addrace));
- memset (sd->addsize, 0, sizeof (sd->addsize));
- memset (sd->addele_, 0, sizeof (sd->addele_));
- memset (sd->addrace_, 0, sizeof (sd->addrace_));
- memset (sd->addsize_, 0, sizeof (sd->addsize_));
- memset (sd->subele, 0, sizeof (sd->subele));
- memset (sd->subrace, 0, sizeof (sd->subrace));
- memset (sd->addeff, 0, sizeof (sd->addeff));
- memset (sd->addeff2, 0, sizeof (sd->addeff2));
- memset (sd->reseff, 0, sizeof (sd->reseff));
- memset (&sd->special_state, 0, sizeof (sd->special_state));
- memset (sd->weapon_coma_ele, 0, sizeof (sd->weapon_coma_ele));
- memset (sd->weapon_coma_race, 0, sizeof (sd->weapon_coma_race));
- sd->watk_ = 0; //二刀流用(仮)
- sd->watk_2 = 0;
- sd->atk_ele_ = 0;
- sd->star_ = 0;
- sd->overrefine_ = 0;
- sd->aspd_rate = 100;
- sd->speed_rate = 100;
- sd->hprecov_rate = 100;
- sd->sprecov_rate = 100;
- sd->critical_def = 0;
- sd->double_rate = 0;
- sd->near_attack_def_rate = sd->long_attack_def_rate = 0;
- sd->atk_rate = sd->matk_rate = 100;
- sd->ignore_def_ele = sd->ignore_def_race = 0;
- sd->ignore_def_ele_ = sd->ignore_def_race_ = 0;
- sd->ignore_mdef_ele = sd->ignore_mdef_race = 0;
- sd->arrow_cri = 0;
- sd->magic_def_rate = sd->misc_def_rate = 0;
- memset (sd->arrow_addele, 0, sizeof (sd->arrow_addele));
- memset (sd->arrow_addrace, 0, sizeof (sd->arrow_addrace));
- memset (sd->arrow_addsize, 0, sizeof (sd->arrow_addsize));
- memset (sd->arrow_addeff, 0, sizeof (sd->arrow_addeff));
- memset (sd->arrow_addeff2, 0, sizeof (sd->arrow_addeff2));
- memset (sd->magic_addele, 0, sizeof (sd->magic_addele));
- memset (sd->magic_addrace, 0, sizeof (sd->magic_addrace));
- memset (sd->magic_subrace, 0, sizeof (sd->magic_subrace));
- sd->perfect_hit = 0;
- sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
- sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
- sd->def_ratio_atk_ele = sd->def_ratio_atk_ele_ = 0;
- sd->def_ratio_atk_race = sd->def_ratio_atk_race_ = 0;
- sd->get_zeny_num = 0;
- sd->add_damage_class_count = sd->add_damage_class_count_ =
- sd->add_magic_damage_class_count = 0;
- sd->add_def_class_count = sd->add_mdef_class_count = 0;
- sd->monster_drop_item_count = 0;
- memset (sd->add_damage_classrate, 0, sizeof (sd->add_damage_classrate));
- memset (sd->add_damage_classrate_, 0, sizeof (sd->add_damage_classrate_));
- memset (sd->add_magic_damage_classrate, 0,
- sizeof (sd->add_magic_damage_classrate));
- memset (sd->add_def_classrate, 0, sizeof (sd->add_def_classrate));
- memset (sd->add_mdef_classrate, 0, sizeof (sd->add_mdef_classrate));
- memset (sd->monster_drop_race, 0, sizeof (sd->monster_drop_race));
- memset (sd->monster_drop_itemrate, 0, sizeof (sd->monster_drop_itemrate));
- sd->speed_add_rate = sd->aspd_add_rate = 100;
- sd->double_add_rate = sd->perfect_hit_add = sd->get_zeny_add_num = 0;
- sd->splash_range = sd->splash_add_range = 0;
- sd->autospell_id = sd->autospell_lv = sd->autospell_rate = 0;
- sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate =
- sd->sp_drain_per = 0;
- sd->hp_drain_rate_ = sd->hp_drain_per_ = sd->sp_drain_rate_ =
- sd->sp_drain_per_ = 0;
- sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0;
- sd->magic_damage_return = 0; //AppleGirl Was Here
- sd->random_attack_increase_add = sd->random_attack_increase_per = 0;
- if (!sd->disguiseflag && sd->disguise)
- {
- sd->disguise = 0;
- pc_set_weapon_look (sd);
- clif_changelook (&sd->bl, LOOK_SHIELD, sd->status.shield);
- clif_changelook (&sd->bl, LOOK_HEAD_BOTTOM, sd->status.head_bottom);
- clif_changelook (&sd->bl, LOOK_HEAD_TOP, sd->status.head_top);
- clif_changelook (&sd->bl, LOOK_HEAD_MID, sd->status.head_mid);
- clif_clearchar (&sd->bl, 9);
- pc_setpos (sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
- }
- sd->spellpower_bonus_target = 0;
- for (i = 0; i < MAX_EQUIP_SIZE; i++)
- {
- //+++ skiping arrow slot?
- if (i == 10)
- continue;
- index = sd->equip_index[i];
- if (index < 0 || index >= MAX_INVENTORY)
- continue;
- if (i == 9 && sd->equip_index[8] == index)
- continue;
- if (i == 5 && sd->equip_index[4] == index)
- continue;
- if (i == 6
- && (sd->equip_index[5] == index || sd->equip_index[4] == index))
- continue;
- if (sd->inventory_data[index])
- {
- sd->spellpower_bonus_target +=
- sd->inventory_data[index]->magic_bonus;
- if (sd->inventory_data[index]->type == 4)
- {
- if (sd->status.inventory[index].card[0] != 0x00ff
- && sd->status.inventory[index].card[0] != 0x00fe
- && sd->status.inventory[index].card[0] != (short) 0xff00)
- {
- int j;
- for (j = 0; j < sd->inventory_data[index]->slot; j++)
- { // カード
- int c = sd->status.inventory[index].card[j];
- if (c > 0)
- {
- argrec_t arg[2];
- arg[0].name = "@slotId";
- arg[0].v.i = i;
- arg[1].name = "@itemId";
- arg[1].v.i = sd->inventory_data[index]->nameid;
- if (i == 8
- && sd->status.inventory[index].equip == 0x20)
- sd->state.lr_flag = 1;
- run_script_l (itemdb_equipscript (c), 0, sd->bl.id,
- 0, 2, arg);
- sd->state.lr_flag = 0;
- }
- }
- }
- }
- else if (sd->inventory_data[index]->type == 5)
- { // 防具
- if (sd->status.inventory[index].card[0] != 0x00ff
- && sd->status.inventory[index].card[0] != 0x00fe
- && sd->status.inventory[index].card[0] != (short) 0xff00)
- {
- int j;
- for (j = 0; j < sd->inventory_data[index]->slot; j++)
- { // カード
- int c = sd->status.inventory[index].card[j];
- if (c > 0) {
- argrec_t arg[2];
- arg[0].name = "@slotId";
- arg[0].v.i = i;
- arg[1].name = "@itemId";
- arg[1].v.i = sd->inventory_data[index]->nameid;
- run_script_l (itemdb_equipscript (c), 0, sd->bl.id,
- 0, 2, arg);
- }
- }
- }
- }
- }
- }
- #ifdef USE_ASTRAL_SOUL_SKILL
- if (sd->spellpower_bonus_target < 0)
- sd->spellpower_bonus_target =
- (sd->spellpower_bonus_target * 256) /
- (MIN (128 + skill_power (sd, TMW_ASTRAL_SOUL), 256));
- #endif
- if (sd->spellpower_bonus_target < sd->spellpower_bonus_current)
- sd->spellpower_bonus_current = sd->spellpower_bonus_target;
- wele = sd->atk_ele;
- wele_ = sd->atk_ele_;
- def_ele = sd->def_ele;
- memcpy (sd->paramcard, sd->parame, sizeof (sd->paramcard));
- // 装備品によるステータス変化はここで実行
- for (i = 0; i < MAX_EQUIP_SIZE; i++)
- {
- //+++ skip arrow slot?
- if (i == 10)
- continue;
- index = sd->equip_index[i];
- if (index < 0 || index >= MAX_INVENTORY)
- continue;
- if (i == 9 && sd->equip_index[8] == index)
- continue;
- if (i == 5 && sd->equip_index[4] == index)
- continue;
- if (i == 6
- && (sd->equip_index[5] == index || sd->equip_index[4] == index))
- continue;
- if (sd->inventory_data[index])
- {
- sd->def += sd->inventory_data[index]->def;
- if (sd->inventory_data[index]->type == 4)
- {
- int r, wlv = sd->inventory_data[index]->wlv;
- if (i == 8 && sd->status.inventory[index].equip == 0x20)
- {
- //二刀流用データ入力
- sd->watk_ += sd->inventory_data[index]->atk;
- sd->watk_2 = (r = sd->status.inventory[index].refine) * // 精錬攻撃力
- refinebonus[wlv][0];
- if ((r -= refinebonus[wlv][2]) > 0) // 過剰精錬ボーナス
- sd->overrefine_ = r * refinebonus[wlv][1];
- if (sd->status.inventory[index].card[0] == 0x00ff)
- { // 製造武器
- sd->star_ = (sd->status.inventory[index].card[1] >> 8); // 星のかけら
- wele_ = (sd->status.inventory[index].card[1] & 0x0f); // 属 性
- }
- sd->attackrange_…
Large files files are truncated, but you can click here to view the full file