//Exp share and added zeny share [Valaris] int party_exp_share(struct party_data *p, struct block_list *src, unsigned int base_exp, unsigned int job_exp, int zeny) { struct map_session_data *sd[MAX_PARTY]; unsigned int i, c; #ifdef RENEWAL_EXP uint32 base_exp_bonus, job_exp_bonus; #endif nullpo_ret(p); //Count the number of players eligible for exp sharing for (i = c = 0; i < MAX_PARTY; i++) { if ((sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c]))) continue; c++; } if (c < 1) return 0; base_exp /= c; job_exp /= c; zeny /= c; if (battle_config.party_even_share_bonus && c > 1) { double bonus = 100 + battle_config.party_even_share_bonus * (c - 1); if (base_exp) base_exp = (unsigned int)cap_value(base_exp * bonus / 100, 0, UINT_MAX); if (job_exp) job_exp = (unsigned int)cap_value(job_exp * bonus / 100, 0, UINT_MAX); if (zeny) zeny = (unsigned int)cap_value(zeny * bonus / 100, INT_MIN, INT_MAX); } #ifdef RENEWAL_EXP base_exp_bonus = base_exp; job_exp_bonus = job_exp; #endif for (i = 0; i < c; i++) { #ifdef RENEWAL_EXP if (!(src && src->type == BL_MOB && ((TBL_MOB *)src)->db->mexp)) { TBL_MOB *md = BL_CAST(BL_MOB, src); int rate = 0; if (!md) return 0; rate = pc_level_penalty_mod(sd[i], md->db->lv, md->db->status.class_, 1); base_exp = (unsigned int)cap_value(base_exp_bonus * rate / 100, 1, UINT_MAX); job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX); } #endif pc_gainexp(sd[i], src, base_exp, job_exp, false); if (zeny) //Zeny from mobs [Valaris] pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL); } return 0; }
/** Party EXP and Zeny sharing * @param p Party data * @param src EXP source (for renewal level penalty) * @param base_exp Base EXP gained from killed mob * @param job_exp Job EXP gained from killed mob * @param zeny Zeny gained from killed mob * @author Valaris **/ void party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny) { struct map_session_data* sd[MAX_PARTY]; unsigned int i, c; #ifdef RENEWAL_EXP TBL_MOB *md = BL_CAST(BL_MOB, src); if (!md) return; #endif nullpo_retv(p); // count the number of players eligible for exp sharing for (i = c = 0; i < MAX_PARTY; i++) { if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) ) continue; c++; } if (c < 1) return; base_exp/=c; job_exp/=c; zeny/=c; if (battle_config.party_even_share_bonus && c > 1) { double bonus = 100 + battle_config.party_even_share_bonus*(c-1); if (base_exp) base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX); if (job_exp) job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX); if (zeny) zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX); } for (i = 0; i < c; i++) { #ifdef RENEWAL_EXP uint32 base_gained = base_exp, job_gained = job_exp; if (base_exp || job_exp) { int rate = pc_level_penalty_mod(md->level - sd[i]->status.base_level, md->db->status.class_, md->db->status.mode, 1); if (rate != 100) { if (base_exp) base_gained = (unsigned int)cap_value(apply_rate(base_exp, rate), 1, UINT_MAX); if (job_exp) job_gained = (unsigned int)cap_value(apply_rate(job_exp, rate), 1, UINT_MAX); } } pc_gainexp(sd[i], src, base_gained, job_gained, 0); #else pc_gainexp(sd[i], src, base_exp, job_exp, 0); #endif if (zeny) // zeny from mobs [Valaris] pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL); } }
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) { struct skill_condition req; uint16 skill_id, skill_lv; int i; nullpo_ret(ed); nullpo_ret(bl); if( !ed->master ) return 0; if( ed->target_id ) elemental_unlocktarget(ed); // Remove previous target. ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE)); if( i == MAX_ELESKILLTREE ) return 0; skill_id = ed->db->skill[i].id; skill_lv = ed->db->skill[i].lv; if( elemental_skillnotok(skill_id, ed) ) return 0; if( ed->ud.skilltimer != INVALID_TIMER ) return 0; else if( DIFF_TICK(tick, ed->ud.canact_tick) < 0 ) return 0; ed->target_id = ed->ud.skilltarget = bl->id; // Set new target ed->last_thinktime = tick; // Not in skill range. if( !battle_check_range(&ed->bl,bl,skill_get_range(skill_id,skill_lv)) ) { // Try to walk to the target. if( !unit_walktobl(&ed->bl, bl, skill_get_range(skill_id,skill_lv), 2) ) elemental_unlocktarget(ed); else { // Walking, waiting to be in range. Client don't handle it, then we must handle it here. int walk_dist = distance_bl(&ed->bl,bl) - skill_get_range(skill_id,skill_lv); ed->ud.skill_id = skill_id; ed->ud.skill_lv = skill_lv; if( skill_get_inf(skill_id) & INF_GROUND_SKILL ) ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_pos, ed->bl.id, 0 ); else ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_id, ed->bl.id, 0 ); } return 1; } req = elemental_skill_get_requirements(skill_id, skill_lv); if(req.hp || req.sp){ struct map_session_data *sd = BL_CAST(BL_PC, battle_get_master(&ed->bl)); if( sd ){ if( sd->skill_id_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast (status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) ) return 1; else status_zap(&ed->bl, req.hp, req.sp); } } //Otherwise, just cast the skill. if( skill_get_inf(skill_id) & INF_GROUND_SKILL ) unit_skilluse_pos(&ed->bl, bl->x, bl->y, skill_id, skill_lv); else unit_skilluse_id(&ed->bl, bl->id, skill_id, skill_lv); // Reset target. ed->target_id = 0; return 1; }
void harmony_action_request_global(int task, int id, intptr data) { switch (task) { case HARMTASK_LOGIN_ACTION: chrif_harmony_request((uint8*)data, id); break; case HARMTASK_GET_FD: { TBL_PC *sd = BL_CAST(BL_PC, map_id2bl(id)); *(int32*)data = (sd ? sd->fd : 0); } break; case HARMTASK_SET_LOG_METHOD: log_method = id; break; case HARMTASK_INIT_GROUPS: if (chrif_isconnected()) harmony_register_groups(); else { // Register groups as soon as the char server is available again if (tid_group_register != INVALID_TIMER) _athena_delete_timer(tid_group_register, harmony_group_register_timer); tid_group_register = _athena_add_timer_interval(_athena_gettick()+1000, harmony_group_register_timer, 0, 0, 500); } break; case HARMTASK_RESOLVE_GROUP: #if HARMSW == HARMSW_RATHENA_GROUP *(int32*)data = pc_group_id2level(id); #else *(int32*)data = id; #endif break; case HARMTASK_PACKET: clif_send((const uint8*)data, id, NULL, ALL_CLIENT); break; case HARMTASK_GET_ADMINS: { #if HARMSW == HARMSW_RATHENA_GROUP // Iterate groups and register each group individually current_groupscan_minlevel = id; pc_group_iterate(harmony_iterate_groups_adminlevel); #else // int account_id; int level = id; if (SQL_SUCCESS != SqlStmt_BindParam(admin_stmt, 0, SQLDT_INT, (void*)&level, sizeof(level)) || SQL_SUCCESS != SqlStmt_Execute(admin_stmt)) { ShowError("Fetching GM accounts failed.\n"); Sql_ShowDebug(mmysql_handle); break; } SqlStmt_BindColumn(admin_stmt, 0, SQLDT_INT, &account_id, 0, NULL, NULL); while (SQL_SUCCESS == SqlStmt_NextRow(admin_stmt)) { harm_funcs->zone_register_admin(account_id, false); } #endif break; } case HARMTASK_IS_CHAR_CONNECTED: *(int*)data = chrif_isconnected(); break; default: ShowError("Harmony requested unknown action! (Global; ID=%d)\n", task); ShowError("This indicates that you are running an incompatible version.\n"); break; } }