Peace!
На днях поставил AXE сервер для "своих", да и самому интересно было поковырять это чудо. Поиграв достаточное количество времени за темплара, обнаружил (а вдруг показалось?
), что такие скиллы как
Punishment (стигма-скилл) и
Shining Slash наносят только либо обычный урон, либо критовый, хотя в описании сказано что они должны наносить random damage.
Что это означает на практике? На просторах сети я нашёл следующее описание: такой тип скилла дополнительно имеет множитель, который выбирается от удара к удару произвольным образом. Множители: 0.5x, 1x, 2x, 2.5x.
Далее я расскажу, как я пытался это дело пофиксить. Так как с игровыми серверами я не работал вообще, претендую на медальку "нуб". Критику люблю.
Ближе к теме. Для примера я взял скилл темпла
Shining Slash IV. Смотрим
skill_templates.xml:
PHP код:
<skill_template skill_id="2045" name="STR_SKILL_KN_ShineSlash_G4" nameId="590777" stack="SKILL_KN_SHINESLASH" lvl="4" skilltype="PHYSICAL" skillsubtype="ATTACK" tslot="NONE" activation="ACTIVE" cooldown="180" duration="0" cancel_rate="10">
<initproperties>
<addweaponrange/>
</initproperties>
<startconditions>
<mp value="71" delta="0"/>
</startconditions>
<setproperties>
<firsttarget value="TARGET"/>
<firsttargetrange value="1"/>
<targetrange value="ONLYONE"/>
<targetrelation value="ENEMY"/>
</setproperties>
<effects>
<skillatk value="220" delta="8" e="1" hoptype="DAMAGE"/>
</effects>
<actions>
<mpuse value="71" delta="0"/>
</actions>
</skill_template>
Вроде как он самый. Только вот ничего необычного здесь нету. Ясно только что скилл юзает
effect типа
skillatk.
Ну ок, смотрим что за зверь такой в
skills.xsd:
PHP код:
<xs:element name="skillatk" type="SkillAttackEffect" minOccurs="0" maxOccurs="1"/>
В общем-то понятно, что ничего не понятно. Благодаря уважаемым форумчанам, сложил два и два и отправился прямиком в класс
SkillAttakEffect.java:
PHP код:
/**
* @author ATracer
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SkillAttackEffect")
public class SkillAttackEffect extends DamageEffect {
@Override
public void calculate(Effect effect) {
super.calculate(effect, DamageType.PHYSICAL);
}
}
Ничего интересного и тут нет. Вызывается метод суперкласса и всё. Ну что-ж, смотрим
DamageEffect.java. Приведу ниже только нужную функцию:
PHP код:
public void calculate(Effect effect, DamageType damageType) {
int skillLvl = effect.getSkillLevel();
int valueWithDelta = value + delta * skillLvl;
valueWithDelta = applyActionModifiers(effect, valueWithDelta);
// apply pvp damage ratio
if (effect.getEffected() instanceof Player && effect.getPvpDamage() != 0)
valueWithDelta = Math.round(valueWithDelta * (effect.getPvpDamage() / 100f));
switch (damageType) {
case PHYSICAL:
AttackUtil.calculatePhysicalSkillAttackResult(effect, valueWithDelta);
break;
case MAGICAL:
AttackUtil.calculateMagicalSkillAttackResult(effect, valueWithDelta, getElement());
break;
default:
AttackUtil.calculatePhysicalSkillAttackResult(effect, 0);
}
if (effect.getAttackStatus() != AttackStatus.RESIST && effect.getAttackStatus() != AttackStatus.DODGE || this instanceof MoveBehindEffect)
effect.addSucessEffect(this);
}
Вроде как оно. Тут даже PvP урон считается, проверка на ресист и эвэйд... Недолго думая, решено было править исходник.
Переменная типа
Effect через доступный метод может вернуть йдишник скилла. За неимением других вариантов, я изменял
valueWithDelta. Осталось добавить какой-нибудь свитч и рандом:
PHP код:
switch (effect.getSkillId()) {
case 2045: // Shining Slash IV (Templar)
double rnd = Math.random();
float x = .0f; // rate (x0.5, x1, x2, x2.5)
if(rnd >= 0.0 && rnd <= 0.25)
x = 0.5f;
else if(rnd > 0.25 && rnd <= 0.5)
x = 1.0f;
else if(rnd > 0.5 && rnd <= 0.75)
x = 2.0f;
else if(rnd > 0.75 && rnd < 1.0)
x = 2.5f;
valueWithDelta = Math.round(valueWithDelta * x);
break;
default:
break;
}
После компиляции, скилл реально стал давать произвольный дамаг. Конечно, здесь ещё нужно скорректировать шансы выбора того или иного рейта (думаю, что x0.5 и x2.5 должны выпадать реже, чем x1), ну и кейсов набросать для остальных скиллов (уже в порядке очереди).
Ну а теперь любимая рубрика нуба "Вопросы - Гуру":
1. Я - адекватный?
2. valueWithDelta - то ли я изменяю или нет?
4. Куда вставлять свитч (если, конечно, вставлять) - до или после
apply pvp damage ratio?
Спасибо за внимание