Beispiel #1
0
//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;
}
Beispiel #2
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);
	}
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
	}
}