pulled update

This commit is contained in:
mstoppelli
2018-05-30 15:53:53 -04:00
22 changed files with 515 additions and 185 deletions

View File

@@ -126,8 +126,10 @@ public class SorceryCombineAction implements ModAction {
performer.getCommunicator().sendSafeServerMessage("A new sorcery has been created!"); performer.getCommunicator().sendSafeServerMessage("A new sorcery has been created!");
MiscChanges.sendServerTabMessage("arena", performer.getName()+" has created a new sorcery!", 52, 152, 219); MiscChanges.sendServerTabMessage("arena", performer.getName()+" has created a new sorcery!", 52, 152, 219);
Item sorcery = ItemUtil.createRandomSorcery((byte) (2+Server.rand.nextInt(1))); Item sorcery = ItemUtil.createRandomSorcery((byte) (2+Server.rand.nextInt(1)));
logger.info("Player "+performer.getName()+" created a "+sorcery.getName()+" with "+(3-sorcery.getAuxData())+" charges."); if(sorcery != null) {
logger.info("Player " + performer.getName() + " created a " + sorcery.getName() + " with " + (3 - sorcery.getAuxData()) + " charges.");
performer.getInventory().insertItem(sorcery, true); performer.getInventory().insertItem(sorcery, true);
}
if(newAux >= 0) { if(newAux >= 0) {
first.setAuxData(newAux); first.setAuxData(newAux);
first.setName("sorcery fragment [" + (first.getAuxData() + 1) + "/10]"); first.setName("sorcery fragment [" + (first.getAuxData() + 1) + "/10]");

View File

@@ -3,6 +3,7 @@ package mod.sin.actions.items;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -57,7 +58,7 @@ public class EnchantOrbAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item source, Item object) public List<ActionEntry> getBehavioursFor(Creature performer, Item source, Item object)
{ {
if(performer instanceof Player && source != null && object != null && source.getTemplateId() == EnchantOrb.templateId && source != object){ if(performer instanceof Player && source != null && object != null && source.getTemplateId() == EnchantOrb.templateId && source != object){
return Arrays.asList(actionEntry); return Collections.singletonList(actionEntry);
} }
return null; return null;
} }
@@ -84,8 +85,8 @@ public class EnchantOrbAction implements ModAction {
player.getCommunicator().sendNormalServerMessage("You must use an Enchant Orb to transfer enchants."); player.getCommunicator().sendNormalServerMessage("You must use an Enchant Orb to transfer enchants.");
return true; return true;
} }
if(source.getWurmId() == target.getWurmId()){ if(target.getTemplate().getTemplateId() == EnchantOrb.templateId){
player.getCommunicator().sendNormalServerMessage("You cannot enchant the orb with itself!"); player.getCommunicator().sendNormalServerMessage("You cannot enchant an Enchant Orb with another.");
return true; return true;
} }
ItemSpellEffects effs = source.getSpellEffects(); ItemSpellEffects effs = source.getSpellEffects();
@@ -93,22 +94,49 @@ public class EnchantOrbAction implements ModAction {
player.getCommunicator().sendNormalServerMessage("The "+source.getTemplate().getName()+" has no enchants."); player.getCommunicator().sendNormalServerMessage("The "+source.getTemplate().getName()+" has no enchants.");
return true; return true;
} }
if(!Spell.mayBeEnchanted(target)){ /*if(!Spell.mayBeEnchanted(target)){
player.getCommunicator().sendNormalServerMessage("The "+target.getTemplate().getName()+" may not be enchanted."); player.getCommunicator().sendNormalServerMessage("The "+target.getTemplate().getName()+" may not be enchanted.");
} }*/
ItemSpellEffects teffs = target.getSpellEffects(); ItemSpellEffects teffs = target.getSpellEffects();
if(teffs == null){ if(teffs == null){
teffs = new ItemSpellEffects(target.getWurmId()); teffs = new ItemSpellEffects(target.getWurmId());
} }
for(SpellEffect eff : effs.getEffects()){ for(SpellEffect eff : effs.getEffects()){
Spell spell = Spells.getEnchantment(eff.type); Spell spell = Spells.getEnchantment(eff.type);
boolean canEnchant = Spell.mayBeEnchanted(target); boolean canEnchant = false;// = Spell.mayBeEnchanted(target);
byte type = eff.type; byte type = eff.type;
if(spell == null){ if(spell == null){
logger.info("Error: Enchant for "+eff.type+" doesn't exist."); if(eff.type < -60){ // It's a rune
if(teffs.getNumberOfRuneEffects() > 0){
teffs.getRandomRuneEffect();
player.getCommunicator().sendAlertServerMessage("The "+target.getTemplate().getName()+" already has a rune attached and resists the application of the "+eff.getName()+".");
continue;
}else{
canEnchant = true;
}
}else{
if(teffs.getSpellEffect(type) != null){
float power = teffs.getSpellEffect(type).getPower();
if(power >= 100f){
player.getCommunicator().sendAlertServerMessage("The "+target.getTemplate().getName()+" already has the maximum power for "+eff.getName()+", and refuses to accept more.");
continue;
}else if(power + eff.getPower() > 100){
float difference = 100-power;
eff.setPower(eff.getPower()-difference);
teffs.getSpellEffect(type).setPower(100);
player.getCommunicator().sendSafeServerMessage("The "+eff.getName()+" transfers some of its power to the "+target.getTemplate().getName()+".");
continue;
}else{
teffs.getSpellEffect(type).setPower(effs.getSpellEffect(type).getPower()+power);
effs.removeSpellEffect(type);
player.getCommunicator().sendSafeServerMessage("The "+eff.getName()+" fully transfers to the "+target.getTemplate().getName()+".");
continue; continue;
} }
if(canEnchant){ }else{
canEnchant = true;
}
}
}else {
try { try {
Method m = spell.getClass().getDeclaredMethod("precondition", Skill.class, Creature.class, Item.class); Method m = spell.getClass().getDeclaredMethod("precondition", Skill.class, Creature.class, Item.class);
canEnchant = ReflectionUtil.callPrivateMethod(spell, m, player.getChannelingSkill(), performer, target); canEnchant = ReflectionUtil.callPrivateMethod(spell, m, player.getChannelingSkill(), performer, target);
@@ -117,11 +145,26 @@ public class EnchantOrbAction implements ModAction {
} }
} }
if(canEnchant){ if(canEnchant){
if(teffs.getSpellEffect(type) != null){
if(teffs.getSpellEffect(type).getPower() >= eff.getPower()) {
player.getCommunicator().sendAlertServerMessage("The " + target.getTemplate().getName() + " already has a more powerful " + eff.getName() + " and resists the transfer.");
continue;
}else{
teffs.getSpellEffect(type).setPower(eff.getPower());
effs.removeSpellEffect(type);
player.getCommunicator().sendSafeServerMessage("The "+eff.getName()+" replaces the existing enchant.");
continue;
}
}
SpellEffect newEff = new SpellEffect(target.getWurmId(), type, eff.getPower(), 20000000); SpellEffect newEff = new SpellEffect(target.getWurmId(), type, eff.getPower(), 20000000);
teffs.addSpellEffect(newEff); teffs.addSpellEffect(newEff);
Items.destroyItem(source.getWurmId()); effs.removeSpellEffect(type);
player.getCommunicator().sendSafeServerMessage("The "+eff.getName()+" transfers to the "+target.getTemplate().getName()+"."); player.getCommunicator().sendSafeServerMessage("The "+eff.getName()+" transfers to the "+target.getTemplate().getName()+".");
} }
}
if(effs.getEffects().length == 0){
player.getCommunicator().sendSafeServerMessage("The "+source.getTemplate().getName()+" exhausts the last of its magic and vanishes.");
Items.destroyItem(source.getWurmId());
} }
}else{ }else{
logger.info("Somehow a non-player activated an Enchant Orb..."); logger.info("Somehow a non-player activated an Enchant Orb...");

View File

@@ -0,0 +1,130 @@
package mod.sin.actions.items;
import com.wurmonline.server.FailedException;
import com.wurmonline.server.Items;
import com.wurmonline.server.behaviours.Action;
import com.wurmonline.server.behaviours.ActionEntry;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemFactory;
import com.wurmonline.server.items.ItemSpellEffects;
import com.wurmonline.server.items.NoSuchTemplateException;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.skills.Skill;
import com.wurmonline.server.spells.Spell;
import com.wurmonline.server.spells.SpellEffect;
import com.wurmonline.server.spells.Spells;
import mod.sin.items.EnchantOrb;
import mod.sin.items.EternalOrb;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modsupport.actions.ActionPerformer;
import org.gotti.wurmunlimited.modsupport.actions.BehaviourProvider;
import org.gotti.wurmunlimited.modsupport.actions.ModAction;
import org.gotti.wurmunlimited.modsupport.actions.ModActions;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class EternalOrbAction implements ModAction {
private static Logger logger = Logger.getLogger(EternalOrbAction.class.getName());
private final short actionId;
private final ActionEntry actionEntry;
public EternalOrbAction() {
logger.log(Level.WARNING, "EternalOrbAction()");
actionId = (short) ModActions.getNextActionId();
actionEntry = ActionEntry.createEntry(
actionId,
"Absorb enchants",
"absorbing",
new int[0]
//new int[] { 6 /* ACTION_TYPE_NOMOVE */ } // 6 /* ACTION_TYPE_NOMOVE */, 48 /* ACTION_TYPE_ENEMY_ALWAYS */, 36 /* ACTION_TYPE_ALWAYS_USE_ACTIVE_ITEM */
);
ModActions.registerAction(actionEntry);
}
@Override
public BehaviourProvider getBehaviourProvider()
{
return new BehaviourProvider() {
// Menu with activated object
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item source, Item object)
{
if(performer instanceof Player && source != null && object != null && source.getTemplateId() == EternalOrb.templateId && source != object){
return Collections.singletonList(actionEntry);
}
return null;
}
};
}
@Override
public ActionPerformer getActionPerformer()
{
return new ActionPerformer() {
@Override
public short getActionId() {
return actionId;
}
// With activated object
@Override
public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter)
{
if(performer instanceof Player){
Player player = (Player) performer;
if(source.getTemplate().getTemplateId() != EternalOrb.templateId){
player.getCommunicator().sendNormalServerMessage("You must use an Eternal Orb to absorb enchants.");
return true;
}
if(source.getWurmId() == target.getWurmId()){
player.getCommunicator().sendNormalServerMessage("You cannot absorb the orb with itself!");
return true;
}
ItemSpellEffects teffs = target.getSpellEffects();
if(teffs == null || teffs.getEffects().length == 0){
player.getCommunicator().sendNormalServerMessage("The "+target.getTemplate().getName()+" has no enchants.");
return true;
}
try {
Item enchantOrb = ItemFactory.createItem(EnchantOrb.templateId, source.getCurrentQualityLevel(), "");
ItemSpellEffects effs = enchantOrb.getSpellEffects();
if(effs == null){
effs = new ItemSpellEffects(enchantOrb.getWurmId());
}
for(SpellEffect teff : teffs.getEffects()){
byte type = teff.type;
SpellEffect newEff = new SpellEffect(enchantOrb.getWurmId(), type, teff.getPower(), 20000000);
effs.addSpellEffect(newEff);
teffs.removeSpellEffect(type);
player.getCommunicator().sendSafeServerMessage("The "+teff.getName()+" transfers to the "+enchantOrb.getTemplate().getName()+".");
if(enchantOrb.getDescription().equals("")){
enchantOrb.setDescription(newEff.getName().substring(0,1)+String.format("%d", (int) newEff.getPower()));
}else{
enchantOrb.setDescription(enchantOrb.getDescription()+" "+newEff.getName().substring(0,1)+String.format("%d", (int) newEff.getPower()));
}
}
performer.getInventory().insertItem(enchantOrb, true);
Items.destroyItem(source.getWurmId());
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
}else{
logger.info("Somehow a non-player activated an Enchant Orb...");
}
return true;
}
}; // ActionPerformer
}
}

View File

@@ -73,6 +73,7 @@ public class Avenger implements ModCreature, CreatureTypes {
builder.combatDamageType(Wound.TYPE_COLD); builder.combatDamageType(Wound.TYPE_COLD);
builder.maxPercentOfCreatures(0.005f); builder.maxPercentOfCreatures(0.005f);
builder.maxGroupAttackSize(100); builder.maxGroupAttackSize(100);
builder.color(70, 70, 255);
templateId = builder.getTemplateId(); templateId = builder.getTemplateId();
return builder; return builder;

View File

@@ -69,6 +69,7 @@ public class HornedPony implements ModCreature, CreatureTypes {
builder.combatDamageType(Wound.TYPE_INTERNAL); builder.combatDamageType(Wound.TYPE_INTERNAL);
builder.maxPercentOfCreatures(0.001f); builder.maxPercentOfCreatures(0.001f);
builder.maxGroupAttackSize(100); builder.maxGroupAttackSize(100);
builder.color(128, 10, 70);
templateId = builder.getTemplateId(); templateId = builder.getTemplateId();
return builder; return builder;

View File

@@ -53,6 +53,7 @@ public class Ifrit implements ModCreature, CreatureTypes {
builder.baseCombatRating(99.0f); builder.baseCombatRating(99.0f);
builder.combatDamageType(Wound.TYPE_BURN); builder.combatDamageType(Wound.TYPE_BURN);
builder.maxGroupAttackSize(150); builder.maxGroupAttackSize(150);
builder.color(255, 128, 128);
//builder.usesNewAttacks(true); //builder.usesNewAttacks(true);
// float baseDamage, float criticalChance, float baseSpeed, int attackReach, int weightGroup, byte damageType, boolean usesWeapon, int rounds, float waitUntilNextAttack // float baseDamage, float criticalChance, float baseSpeed, int attackReach, int weightGroup, byte damageType, boolean usesWeapon, int rounds, float waitUntilNextAttack

View File

@@ -53,6 +53,7 @@ public class Lilith implements ModCreature, CreatureTypes {
builder.baseCombatRating(99.0f); builder.baseCombatRating(99.0f);
builder.combatDamageType(Wound.TYPE_INFECTION); builder.combatDamageType(Wound.TYPE_INFECTION);
builder.maxGroupAttackSize(150); builder.maxGroupAttackSize(150);
builder.color(128, 0, 0);
//builder.usesNewAttacks(true); //builder.usesNewAttacks(true);
// float baseDamage, float criticalChance, float baseSpeed, int attackReach, int weightGroup, byte damageType, boolean usesWeapon, int rounds, float waitUntilNextAttack // float baseDamage, float criticalChance, float baseSpeed, int attackReach, int weightGroup, byte damageType, boolean usesWeapon, int rounds, float waitUntilNextAttack

View File

@@ -54,6 +54,7 @@ public class LilithZombie implements ModCreature, CreatureTypes {
builder.combatDamageType(Wound.TYPE_INFECTION); builder.combatDamageType(Wound.TYPE_INFECTION);
builder.maxPercentOfCreatures(0.005f); builder.maxPercentOfCreatures(0.005f);
builder.maxGroupAttackSize(100); builder.maxGroupAttackSize(100);
builder.color(128, 10, 10);
templateId = builder.getTemplateId(); templateId = builder.getTemplateId();
return builder; return builder;

View File

@@ -3,6 +3,7 @@ package mod.sin.items;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.wurmonline.server.items.Materials;
import org.gotti.wurmunlimited.modsupport.ItemTemplateBuilder; import org.gotti.wurmunlimited.modsupport.ItemTemplateBuilder;
import com.wurmonline.server.MiscConstants; import com.wurmonline.server.MiscConstants;
@@ -32,7 +33,7 @@ public class EnchantOrb implements ItemTypes, MiscConstants {
itemBuilder.modelName("model.artifact.orbdoom"); itemBuilder.modelName("model.artifact.orbdoom");
itemBuilder.difficulty(5.0f); itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500); itemBuilder.weightGrams(500);
itemBuilder.material((byte)52); itemBuilder.material(Materials.MATERIAL_CRYSTAL);
itemBuilder.value(50000); itemBuilder.value(50000);
itemBuilder.isTraded(true); itemBuilder.isTraded(true);

View File

@@ -0,0 +1,43 @@
package mod.sin.items;
import com.wurmonline.server.MiscConstants;
import com.wurmonline.server.items.ItemTemplate;
import com.wurmonline.server.items.ItemTypes;
import com.wurmonline.server.items.Materials;
import org.gotti.wurmunlimited.modsupport.ItemTemplateBuilder;
import java.io.IOException;
import java.util.logging.Logger;
public class EternalOrb implements ItemTypes, MiscConstants {
public static Logger logger = Logger.getLogger(EternalOrb.class.getName());
public static int templateId;
public void createTemplate() throws IOException{
String name = "eternal orb";
ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.item.eternal.orb");
itemBuilder.name(name, "eternal orbs", "Legends say it consumes magic from an object, and moves it to another.");
itemBuilder.itemTypes(new short[]{
ItemTypes.ITEM_TYPE_FULLPRICE,
ItemTypes.ITEM_TYPE_NOSELLBACK,
ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE
});
itemBuilder.imageNumber((short) 819);
itemBuilder.behaviourType((short) 1);
itemBuilder.combatDamage(0);
itemBuilder.decayTime(Long.MAX_VALUE);
itemBuilder.dimensions(1, 1, 1);
itemBuilder.primarySkill((int) NOID);
itemBuilder.bodySpaces(EMPTY_BYTE_PRIMITIVE_ARRAY);
itemBuilder.modelName("model.artifact.orbdoom");
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500);
itemBuilder.material(Materials.MATERIAL_CRYSTAL);
itemBuilder.value(200000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();
templateId = template.getTemplateId();
logger.info(name+" TemplateID: "+templateId);
}
}

View File

@@ -757,8 +757,8 @@ public class Arena {
Util.setReason("Reduce player vs player damage by half."); Util.setReason("Reduce player vs player damage by half.");
CtClass ctCombatHandler = classPool.get("com.wurmonline.server.creatures.CombatHandler"); CtClass ctCombatHandler = classPool.get("com.wurmonline.server.creatures.CombatHandler");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER && ($1.isDominated() || $1.isPlayer()) && $0.creature.isPlayer()){" + replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER && ($1.isDominated() || $1.isPlayer()) && $0.creature.isPlayer()){" +
" logger.info(\"Detected player hit against player/pet opponent. Halving damage.\");" + //" logger.info(\"Detected player hit against player/pet opponent. Halving damage.\");" +
" $3 = $3 * 0.5d;" + " $3 = $3 * 0.7d;" +
"}"; "}";
Util.insertBeforeDeclared(thisClass, ctCombatHandler, "setDamage", replace); Util.insertBeforeDeclared(thisClass, ctCombatHandler, "setDamage", replace);

View File

@@ -195,7 +195,7 @@ public class Bounty {
//ctCreatureStatus.getDeclaredMethod("getSizeMod").setBody("{return mod.sin.wyvern.bestiary.MethodsBestiary.getAdjustedSizeMod(this);}"); //ctCreatureStatus.getDeclaredMethod("getSizeMod").setBody("{return mod.sin.wyvern.bestiary.MethodsBestiary.getAdjustedSizeMod(this);}");
// -- Enable adjusting color for creatures -- // // -- Enable adjusting color for creatures -- //
CtClass ctCreatureTemplate = classPool.get("com.wurmonline.server.creatures.CreatureTemplate"); /*CtClass ctCreatureTemplate = classPool.get("com.wurmonline.server.creatures.CreatureTemplate");
replace = "if("+MethodsBestiary.class.getName()+".checkColorTemplate(this)){" replace = "if("+MethodsBestiary.class.getName()+".checkColorTemplate(this)){"
+ " return "+MethodsBestiary.class.getName()+".getCreatureColorRed(this);" + " return "+MethodsBestiary.class.getName()+".getCreatureColorRed(this);"
+ "}"; + "}";
@@ -207,7 +207,7 @@ public class Bounty {
replace = "if("+MethodsBestiary.class.getName()+".checkColorTemplate(this)){" replace = "if("+MethodsBestiary.class.getName()+".checkColorTemplate(this)){"
+ " return "+MethodsBestiary.class.getName()+".getCreatureColorBlue(this);" + " return "+MethodsBestiary.class.getName()+".getCreatureColorBlue(this);"
+ "}"; + "}";
Util.insertBeforeDeclared(thisClass, ctCreatureTemplate, "getColorBlue", replace); Util.insertBeforeDeclared(thisClass, ctCreatureTemplate, "getColorBlue", replace);*/
/*ctCreatureTemplate.getDeclaredMethod("getColorRed").insertBefore("if(mod.sin.wyvern.bestiary.MethodsBestiary.checkColorTemplate(this)){" /*ctCreatureTemplate.getDeclaredMethod("getColorRed").insertBefore("if(mod.sin.wyvern.bestiary.MethodsBestiary.checkColorTemplate(this)){"
+ " return mod.sin.wyvern.bestiary.MethodsBestiary.getCreatureColorRed(this);" + " return mod.sin.wyvern.bestiary.MethodsBestiary.getCreatureColorRed(this);"
+ "}"); + "}");

View File

@@ -1,6 +1,7 @@
package mod.sin.wyvern; package mod.sin.wyvern;
import com.wurmonline.server.Server; import com.wurmonline.server.Server;
import com.wurmonline.server.Servers;
import com.wurmonline.server.bodys.Wound; import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.bodys.Wounds; import com.wurmonline.server.bodys.Wounds;
import com.wurmonline.server.creatures.Creature; import com.wurmonline.server.creatures.Creature;
@@ -66,6 +67,33 @@ public class CombatChanges {
return mult; return mult;
} }
public static int getLifeTransferAmountModifier(Wound wound, int initial){
byte type = wound.getType();
if(type == Wound.TYPE_ACID || type == Wound.TYPE_BURN || type == Wound.TYPE_COLD){
initial *= 0.5;
}else if(type == Wound.TYPE_INTERNAL || type == Wound.TYPE_INFECTION || type == Wound.TYPE_POISON){
initial *= 0.3;
}
return initial;
}
public static float getLifeTransferModifier(Creature creature, Creature defender){
if(Servers.localServer.PVPSERVER && (defender.isDominated() || defender.isPlayer()) && creature.isPlayer()){
return 0.5f;
}
return 1.0f;
}
public static void doLifeTransfer(Creature creature, Creature defender, Item attWeapon, double defdamage, float armourMod){
float lifeTransfer = attWeapon.getSpellLifeTransferModifier()*getLifeTransferModifier(creature, defender);
Wound[] w;
if (lifeTransfer > 0.0f && defdamage * (double)armourMod * (double)lifeTransfer / (double)(creature.isChampion() ? 1000.0f : 500.0f) > 500.0 && creature.getBody() != null && creature.getBody().getWounds() != null && (w = creature.getBody().getWounds().getWounds()).length > 0) {
int amount = - (int)(defdamage * (double)lifeTransfer / (double)(creature.isChampion() ? 1000.0f : (creature.getCultist() != null && creature.getCultist().healsFaster() ? 250.0f : 500.0f)));
amount = getLifeTransferAmountModifier(w[0], amount);
w[0].modifySeverity(amount);
}
}
public static float getAdjustedOakshell(Creature defender, Item armour, float armourMod){ public static float getAdjustedOakshell(Creature defender, Item armour, float armourMod){
if(defender != null && armour == null){ if(defender != null && armour == null){
float oakshellPower = defender.getBonusForSpellEffect(Enchants.CRET_OAKSHELL); float oakshellPower = defender.getBonusForSpellEffect(Enchants.CRET_OAKSHELL);
@@ -111,13 +139,76 @@ public class CombatChanges {
} }
} }
} }
public static boolean canDoDamage(double damage, Creature attacker, Creature defender) {
public static boolean canDoDamage(double damage, Creature attacker, Creature defender, Item weapon) { //logger.info(String.format("canDoDamage from %s to %s - %.1f", attacker.getName(), defender.getName(), damage));
logger.info(String.format("canDoDamage from %s to %s with %s - %.1f", attacker.getName(), defender.getName(), weapon.getName(), damage));
return damage > 1D; return damage > 1D;
} }
static void patchCombatDamageCheck(ClassPool classPool) throws NotFoundException, BadBytecode { static void patchCombatDamageCheckCombatEngine(ClassPool classPool) throws NotFoundException, BadBytecode {
CtClass cls = classPool.getCtClass("com.wurmonline.server.combat.CombatEngine");
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
CtClass ctString = classPool.get("java.lang.String");
CtClass ctBattle = classPool.get("com.wurmonline.server.combat.Battle");
CtClass ctCombatEngine = classPool.get("com.wurmonline.server.combat.CombatEngine");
// @Nullable Creature performer, Creature defender, byte type, int pos, double damage, float armourMod,
// String attString, @Nullable Battle battle, float infection, float poison, boolean archery, boolean alreadyCalculatedResist
CtClass[] params1 = {
ctCreature,
ctCreature,
CtClass.byteType,
CtClass.intType,
CtClass.doubleType,
CtClass.floatType,
ctString,
ctBattle,
CtClass.floatType,
CtClass.floatType,
CtClass.booleanType,
CtClass.booleanType
};
String desc1 = Descriptor.ofMethod(CtClass.booleanType, params1);
CtMethod method = cls.getMethod("addWound", desc1);
//CtMethod method = cls.getMethod("setDamage", "(Lcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/items/Item;DBB)Z");
MethodInfo methodInfo = method.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
ConstPool constPool = codeAttribute.getConstPool();
CodeIterator codeIterator = codeAttribute.iterator();
// Scan through all the bytecode - look for a multiplication followed by comparing
while (codeIterator.hasNext()) {
int pos = codeIterator.next();
int op = codeIterator.byteAt(pos);
if (op != CodeIterator.DMUL) continue; // not multiplication - continue
op = codeIterator.byteAt(++pos);
if (op == CodeIterator.LDC2_W && codeIterator.byteAt(pos + 3) == CodeIterator.DCMPL) {
// found the pattern, check the value it's comparing to
int ref = codeIterator.u16bitAt(pos + 1);
double val = constPool.getDoubleInfo(ref);
if (val == 500.0) {
// here it is, generate new code to insert
// We'll be calling canDoDamage, the first parameter (damage) is already on the stack, prepare the rest
Bytecode newCode = new Bytecode(constPool);
newCode.add(Bytecode.ALOAD_0); // performer - first parameter of addWound
newCode.add(Bytecode.ALOAD_1); // defender - first parameter of addWound
// call our methor, result is left on the stack
newCode.addInvokestatic(
CombatChanges.class.getName(), "canDoDamage",
"(DLcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/creatures/Creature;)Z");
// The code we're replacing is 4 bytes - LDC2_W, 2byte reference and DCMPL
// Insert a gap for to match the size of the new code
codeIterator.insertGap(pos, newCode.getSize() - 4);
// And put the new code
codeIterator.write(newCode.get(), pos);
}
}
}
}
static void patchCombatDamageCheckCombatHandler(ClassPool classPool) throws NotFoundException, BadBytecode {
CtClass cls = classPool.getCtClass("com.wurmonline.server.creatures.CombatHandler"); CtClass cls = classPool.getCtClass("com.wurmonline.server.creatures.CombatHandler");
CtMethod method = cls.getMethod("setDamage", "(Lcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/items/Item;DBB)Z"); CtMethod method = cls.getMethod("setDamage", "(Lcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/items/Item;DBB)Z");
MethodInfo methodInfo = method.getMethodInfo(); MethodInfo methodInfo = method.getMethodInfo();
@@ -142,12 +233,11 @@ public class CombatChanges {
newCode.add(Bytecode.ALOAD_0); // this newCode.add(Bytecode.ALOAD_0); // this
newCode.addGetfield(cls, "creature", "Lcom/wurmonline/server/creatures/Creature;"); // this.creature newCode.addGetfield(cls, "creature", "Lcom/wurmonline/server/creatures/Creature;"); // this.creature
newCode.add(Bytecode.ALOAD_1); // defender - first parameter of setDamage newCode.add(Bytecode.ALOAD_1); // defender - first parameter of setDamage
newCode.add(Bytecode.ALOAD_2); // weapon - second parameter of setDamage
// call our methor, result is left on the stack // call our methor, result is left on the stack
newCode.addInvokestatic( newCode.addInvokestatic(
CombatChanges.class.getName(), "canDoDamage", CombatChanges.class.getName(), "canDoDamage",
"(DLcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/items/Item;)Z"); "(DLcom/wurmonline/server/creatures/Creature;Lcom/wurmonline/server/creatures/Creature;)Z");
// The code we're replacing is 4 bytes - LDC2_W, 2byte reference and DCMPL // The code we're replacing is 4 bytes - LDC2_W, 2byte reference and DCMPL
// Insert a gap for to match the size of the new code // Insert a gap for to match the size of the new code
@@ -160,6 +250,7 @@ public class CombatChanges {
} }
} }
public static void preInit(){ public static void preInit(){
try{ try{
ClassPool classPool = HookManager.getInstance().getClassPool(); ClassPool classPool = HookManager.getInstance().getClassPool();
@@ -271,13 +362,34 @@ public class CombatChanges {
Util.instrumentDeclared(thisClass, ctWound, "poll", "checkInfection", replace); Util.instrumentDeclared(thisClass, ctWound, "poll", "checkInfection", replace);
Util.instrumentDeclared(thisClass, ctWound, "poll", "checkPoison", replace); Util.instrumentDeclared(thisClass, ctWound, "poll", "checkPoison", replace);
//patchCombatDamageCheck(classPool); Util.setReason("Allow Life Transfer to stack with Rotting Touch (Mechanics-Wise).");
//patchCombatDamageCheckAddWound(classPool); replace = CombatChanges.class.getName()+".doLifeTransfer(this.creature, defender, attWeapon, defdamage, armourMod);"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "isWeaponCrush", replace);
Util.setReason("Reduce Life Transfer power on PvP.");
replace = "$_ = $proceed($$)*"+CombatChanges.class.getName()+".getLifeTransferModifier(this.creature, defender);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "getSpellLifeTransferModifier", replace);
Util.setReason("Reduce Life Transfer healing amount for certain wounds.");
replace = "$_ = $proceed("+CombatChanges.class.getName()+".getLifeTransferAmountModifier($0, $1));";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "modifySeverity", replace);
Util.setReason("Make AOSP not disgustingly broken.");
replace = "if(!this.creature.isPlayer()){" +
" $_ = $proceed($$)*this.creature.addSpellResistance((short) 278);" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "getSpellPainShare", replace);
patchCombatDamageCheckCombatEngine(classPool);
patchCombatDamageCheckCombatHandler(classPool);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) { } catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e); throw new HookException(e);
}/* catch (BadBytecode badBytecode) { } catch (BadBytecode badBytecode) {
badBytecode.printStackTrace(); badBytecode.printStackTrace();
}*/ }
} }
} }

View File

@@ -51,6 +51,7 @@ public class ItemMod {
public static DepthDrill DEPTH_DRILL = new DepthDrill(); public static DepthDrill DEPTH_DRILL = new DepthDrill();
public static DisintegrationRod DISINTEGRATION_ROD = new DisintegrationRod(); public static DisintegrationRod DISINTEGRATION_ROD = new DisintegrationRod();
public static EnchantOrb ENCHANT_ORB = new EnchantOrb(); public static EnchantOrb ENCHANT_ORB = new EnchantOrb();
public static EternalOrb ETERNAL_ORB = new EternalOrb();
public static Eviscerator EVISCERATOR = new Eviscerator(); public static Eviscerator EVISCERATOR = new Eviscerator();
public static FriyanTablet FRIYAN_TABLET = new FriyanTablet(); public static FriyanTablet FRIYAN_TABLET = new FriyanTablet();
public static HugeCrate HUGE_CRATE = new HugeCrate(); public static HugeCrate HUGE_CRATE = new HugeCrate();
@@ -118,6 +119,7 @@ public class ItemMod {
DEPTH_DRILL.createTemplate(); DEPTH_DRILL.createTemplate();
DISINTEGRATION_ROD.createTemplate(); DISINTEGRATION_ROD.createTemplate();
ENCHANT_ORB.createTemplate(); ENCHANT_ORB.createTemplate();
ETERNAL_ORB.createTemplate();
EVISCERATOR.createTemplate(); EVISCERATOR.createTemplate();
FRIYAN_TABLET.createTemplate(); FRIYAN_TABLET.createTemplate();
HUGE_CRATE.createTemplate(); HUGE_CRATE.createTemplate();
@@ -183,6 +185,7 @@ public class ItemMod {
ModActions.registerAction(new DisintegrationRodAction()); ModActions.registerAction(new DisintegrationRodAction());
ModActions.registerAction(new EnchantersCrystalInfuseAction()); ModActions.registerAction(new EnchantersCrystalInfuseAction());
ModActions.registerAction(new EnchantOrbAction()); ModActions.registerAction(new EnchantOrbAction());
ModActions.registerAction(new EternalOrbAction());
ModActions.registerAction(new FriyanTabletAction()); ModActions.registerAction(new FriyanTabletAction());
ModActions.registerAction(new SealedMapAction()); ModActions.registerAction(new SealedMapAction());
ModActions.registerAction(new SupplyDepotAction()); ModActions.registerAction(new SupplyDepotAction());

View File

@@ -25,6 +25,7 @@ import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException; import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager; import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modsupport.ModSupportDb; import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import org.nyxcode.wurm.discordrelay.DiscordRelay;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@@ -37,13 +38,6 @@ import java.util.logging.Logger;
public class MiscChanges { public class MiscChanges {
public static Logger logger = Logger.getLogger(MiscChanges.class.getName()); public static Logger logger = Logger.getLogger(MiscChanges.class.getName());
public static void doLifeTransfer(Creature creature, Item attWeapon, double defdamage, float armourMod){
Wound[] w;
if (attWeapon.getSpellLifeTransferModifier() > 0.0f && defdamage * (double)armourMod * (double)attWeapon.getSpellLifeTransferModifier() / (double)(creature.isChampion() ? 1000.0f : 500.0f) > 500.0 && creature.getBody() != null && creature.getBody().getWounds() != null && (w = creature.getBody().getWounds().getWounds()).length > 0) {
w[0].modifySeverity(- (int)(defdamage * (double)attWeapon.getSpellLifeTransferModifier() / (double)(creature.isChampion() ? 1000.0f : (creature.getCultist() != null && creature.getCultist().healsFaster() ? 250.0f : 500.0f))));
}
}
public static void sendServerTabMessage(String channel, final String message, final int red, final int green, final int blue){ public static void sendServerTabMessage(String channel, final String message, final int red, final int green, final int blue){
// WARNING: Never change this from a new Runnable. Lambdas are a lie and will break everything. // WARNING: Never change this from a new Runnable. Lambdas are a lie and will break everything.
Runnable r = new Runnable() { Runnable r = new Runnable() {
@@ -311,8 +305,8 @@ public class MiscChanges {
// - Enable creature custom colors - (Used for creating custom color creatures eg. Lilith) - // // - Enable creature custom colors - (Used for creating custom color creatures eg. Lilith) - //
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature"); CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
/** replace = "{ return true; }"; /*replace = "{ return true; }";
Util.setBodyDeclared(thisClass, ctCreature, "hasCustomColor", replace);**/ Util.setBodyDeclared(thisClass, ctCreature, "hasCustomColor", replace);*/
// - Increase the amount of checks for new unique spawns by 5x - // // - Increase the amount of checks for new unique spawns by 5x - //
CtClass ctServer = classPool.get("com.wurmonline.server.Server"); CtClass ctServer = classPool.get("com.wurmonline.server.Server");
@@ -390,11 +384,6 @@ public class MiscChanges {
+ "}"; + "}";
Util.instrumentDeclared(thisClass, ctCombatHandler, "checkShield", "max", replace); Util.instrumentDeclared(thisClass, ctCombatHandler, "checkShield", "max", replace);
Util.setReason("Allow Life Transfer to stack with Rotting Touch (Mechanics-Wise).");
replace = MiscChanges.class.getName()+".doLifeTransfer(this.creature, attWeapon, defdamage, armourMod);"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "isWeaponCrush", replace);
// - Allow GM's to bypass the 5 second emote sound limit. - // // - Allow GM's to bypass the 5 second emote sound limit. - //
replace = "if(this.getPower() > 0){" replace = "if(this.getPower() > 0){"
+ " return true;" + " return true;"

View File

@@ -41,6 +41,7 @@ public class PlayerTitles {
} }
} }
public static void preInit(){ public static void preInit(){
// Donations
playerTitles.put("Sindusk", "Phenomenal Feline"); playerTitles.put("Sindusk", "Phenomenal Feline");
customTitles.put("Sindawn", 501); // Developer customTitles.put("Sindawn", 501); // Developer
@@ -70,5 +71,16 @@ public class PlayerTitles {
customTitles.put("Reevi", 807); // Science Guy customTitles.put("Reevi", 807); // Science Guy
customTitles.put("Genocide", 808); // Grand Designer customTitles.put("Genocide", 808); // Grand Designer
donatorTitles.add("Seleas");
customTitles.put("Seleas", 809); // The Crazy Cat Lord
playerTitles.put("Seleas", "No, Really");
donatorTitles.add("Piratemax");
customTitles.put("Piratemax", 810); // Slave
playerTitles.put("Piratemax", "Boy Next Door");
// Other rewards
customTitles.put("Critias", 602);
} }
} }

View File

@@ -9,10 +9,13 @@ import com.wurmonline.server.creatures.NoSuchCreatureException;
import com.wurmonline.server.items.*; import com.wurmonline.server.items.*;
import com.wurmonline.server.skills.Skill; import com.wurmonline.server.skills.Skill;
import com.wurmonline.server.zones.NoSuchZoneException; import com.wurmonline.server.zones.NoSuchZoneException;
import javassist.CannotCompileException;
import javassist.ClassPool; import javassist.ClassPool;
import javassist.CtClass; import javassist.CtClass;
import javassist.NotFoundException; import javassist.NotFoundException;
import javassist.bytecode.Descriptor; import javassist.bytecode.Descriptor;
import javassist.expr.ExprEditor;
import javassist.expr.FieldAccess;
import mod.sin.items.HugeCrate; import mod.sin.items.HugeCrate;
import mod.sin.lib.Util; import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException; import org.gotti.wurmunlimited.modloader.classhooks.HookException;
@@ -55,7 +58,6 @@ public class QualityOfLife {
return false; return false;
} }
} }
public static Item getVehicleSafe(Creature pilot) { public static Item getVehicleSafe(Creature pilot) {
try { try {
if (pilot.getVehicle() != -10) if (pilot.getVehicle() != -10)
@@ -129,7 +131,6 @@ public class QualityOfLife {
QualityOfLife.class.getName()+".vehicleHook(performer, $0);"; QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDescribed(thisClass, ctTileRockBehaviour, "action", desc2, "setDataXY", replace);*/ Util.instrumentDescribed(thisClass, ctTileRockBehaviour, "action", desc2, "setDataXY", replace);*/
Util.setReason("Allow players to surface mine directly into vehicles."); Util.setReason("Allow players to surface mine directly into vehicles.");
CtClass ctTileRockBehaviour = classPool.get("com.wurmonline.server.behaviours.TileRockBehaviour"); CtClass ctTileRockBehaviour = classPool.get("com.wurmonline.server.behaviours.TileRockBehaviour");
replace = "$_ = $proceed($$);" + replace = "$_ = $proceed($$);" +
@@ -180,8 +181,19 @@ public class QualityOfLife {
QualityOfLife.class.getName()+".vehicleHook(performer, $0);"; QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDescribed(thisClass, ctTileRockBehaviour, "createGem", desc2, "putItemInfrontof", replace); Util.instrumentDescribed(thisClass, ctTileRockBehaviour, "createGem", desc2, "putItemInfrontof", replace);
CtClass ctPlayer = classPool.get("com.wurmonline.server.players.Player");
ctPlayer.getMethod("poll", "()Z").instrument(new ExprEditor() {
@Override
public void edit(FieldAccess f) throws CannotCompileException {
if (f.getFieldName().equals("vehicle") && f.isReader())
f.replace("$_ = -10L;");
}
});
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) { } catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e); throw new HookException(e);
} catch (CannotCompileException e) {
e.printStackTrace();
} }
} }
} }

View File

@@ -535,42 +535,44 @@ public class Titans {
int prevDamage = titanDamage.get(titan); int prevDamage = titanDamage.get(titan);
int currentDamage = titan.getStatus().damage; int currentDamage = titan.getStatus().damage;
long wurmid = titan.getWurmId(); long wurmid = titan.getWurmId();
if(titan.isOnSurface() && currentDamage > 0){ if(currentDamage > 0) {
if (titan.isOnSurface()) {
// Advanced Ability // Advanced Ability
int chance; int chance;
int range; int range;
int radius; int radius;
if(currentDamage > 52428) { // 20% if (currentDamage > 52428) { // 20%
chance = 40; chance = 40;
range = 8; range = 7;
radius = 2; radius = 2;
}else if(currentDamage > 32767){ // 50% } else if (currentDamage > 32767) { // 50%
chance = 45; chance = 45;
range = 5; range = 5;
radius = 1; radius = 1;
}else if(currentDamage > 16383){ // 75% } else if (currentDamage > 16383) { // 75%
chance = 55; chance = 55;
range = 4; range = 4;
radius = 1; radius = 1;
}else{ } else {
chance = 60; chance = 60;
range = 3; range = 3;
radius = 0; radius = 0;
} }
if(titanAdvancedTimed.containsKey(wurmid)){ if (titanAdvancedTimed.containsKey(wurmid)) {
int currentChance = titanAdvancedTimed.get(wurmid); int currentChance = titanAdvancedTimed.get(wurmid);
boolean success = Server.rand.nextInt(currentChance) == 0; boolean success = Server.rand.nextInt(currentChance) == 0;
if(success){ if (success) {
performAdvancedAbility(titan, range, radius); performAdvancedAbility(titan, range, radius);
titanAdvancedTimed.put(wurmid, currentChance+chance-1); titanAdvancedTimed.put(wurmid, currentChance + chance - 1);
}else{ } else {
titanAdvancedTimed.put(wurmid, currentChance-1); titanAdvancedTimed.put(wurmid, currentChance - 1);
} }
}else{ } else {
titanAdvancedTimed.put(wurmid, chance); titanAdvancedTimed.put(wurmid, chance);
} }
}else if(!titan.isOnSurface() && Server.rand.nextInt(20) == 0){ } else if (!titan.isOnSurface() && Server.rand.nextInt(20) == 0) {
performAdvancedAbility(titan, 5, 2); performAdvancedAbility(titan, 3, 3);
}
} }
} }
protected static void pollDamageMechanics(Creature titan){ protected static void pollDamageMechanics(Creature titan){
@@ -762,7 +764,7 @@ public class Titans {
int tiley = (int) (minY+(minY*2*Server.rand.nextFloat()))*4;*/ int tiley = (int) (minY+(minY*2*Server.rand.nextFloat()))*4;*/
int[] titanTemplates = {Lilith.templateId, Ifrit.templateId}; int[] titanTemplates = {Lilith.templateId, Ifrit.templateId};
try { try {
Creature.doNew(titanTemplates[Server.rand.nextInt(titanTemplates.length)], spawnX, spawnY, 360f*Server.rand.nextFloat(), 0, "", (byte)0); Creature.doNew(titanTemplates[Server.rand.nextInt(titanTemplates.length)], spawnX, spawnY, 360f*Server.rand.nextFloat(), 1, "", (byte)0);
lastSpawnedTitan = System.currentTimeMillis(); lastSpawnedTitan = System.currentTimeMillis();
updateLastSpawnedTitan(); updateLastSpawnedTitan();
} catch (Exception e) { } catch (Exception e) {

View File

@@ -21,6 +21,8 @@ import com.wurmonline.server.Items;
import com.wurmonline.server.Server; import com.wurmonline.server.Server;
import com.wurmonline.server.creatures.Communicator; import com.wurmonline.server.creatures.Communicator;
import com.wurmonline.server.creatures.Creature; import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.CreatureTemplate;
import com.wurmonline.server.creatures.CreatureTemplateFactory;
import com.wurmonline.server.items.*; import com.wurmonline.server.items.*;
import javassist.bytecode.Descriptor; import javassist.bytecode.Descriptor;
import mod.sin.items.*; import mod.sin.items.*;

View File

@@ -43,76 +43,6 @@ import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
public class MethodsBestiary { public class MethodsBestiary {
protected static Logger logger = Logger.getLogger(MethodsBestiary.class.getName()); protected static Logger logger = Logger.getLogger(MethodsBestiary.class.getName());
public static boolean checkColorTemplate(CreatureTemplate template){
try {
int templateId = template.getTemplateId();
if(templateId == Lilith.templateId){
return true;
}/*else if(templateId == ForestSpider.templateId){
return true;
}*/else if(templateId == Avenger.templateId){
return true;
}else if(templateId == HornedPony.templateId){
return true;
}else if(templateId == LilithZombie.templateId){
return true;
}
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
return false;
}
public static byte getCreatureColorRed(CreatureTemplate template){
try {
int templateId = template.getTemplateId();
/*if(templateId == ForestSpider.templateId){
return (byte)0;
}else */if(templateId == Avenger.templateId){
return (byte)70;
}
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
return (byte)127;
}
public static byte getCreatureColorGreen(CreatureTemplate template){
try {
int templateId = template.getTemplateId();
if(templateId == Lilith.templateId){
return (byte)0;
}else if(templateId == Avenger.templateId){
return (byte)70;
}else if(templateId == HornedPony.templateId){
return (byte)10;
}else if(templateId == LilithZombie.templateId){
return (byte)0;
}
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
return (byte)127;
}
public static byte getCreatureColorBlue(CreatureTemplate template){
try {
int templateId = template.getTemplateId();
if(templateId == Lilith.templateId){
return (byte)0;
}/*else if(templateId == ForestSpider.templateId){
return (byte)0;
}*/else if(templateId == HornedPony.templateId){
return (byte)70;
}else if(templateId == LilithZombie.templateId){
return (byte)0;
}
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
return (byte)127;
}
public static String generateGuardMaleName() { public static String generateGuardMaleName() {
final int rand = Server.rand.nextInt(50); final int rand = Server.rand.nextInt(50);
final String[] firstPart = { "Carl", "John", "Bil", "Strong", "Dare", "Grave", "Hard", "Marde", "Verde", "Vold", "Tolk", "Roe", "Bee", "Har", "Rol", "Ma", "Lo", "Claw", "Drag", "Hug", "Te", "Two", "Fu", "Ji", "La", "Ze", "Jal", "Milk", "War", "Wild", "Hang", "Just", "Fan", "Cloclo", "Buy", "Bought", "Sard", "Smart", "Slo", "Shield", "Dark", "Hung", "Sed", "Sold", "Swing", "Gar", "Dig", "Bur", "Angel", "Sorrow" }; final String[] firstPart = { "Carl", "John", "Bil", "Strong", "Dare", "Grave", "Hard", "Marde", "Verde", "Vold", "Tolk", "Roe", "Bee", "Har", "Rol", "Ma", "Lo", "Claw", "Drag", "Hug", "Te", "Two", "Fu", "Ji", "La", "Ze", "Jal", "Milk", "War", "Wild", "Hang", "Just", "Fan", "Cloclo", "Buy", "Bought", "Sard", "Smart", "Slo", "Shield", "Dark", "Hung", "Sed", "Sold", "Swing", "Gar", "Dig", "Bur", "Angel", "Sorrow" };
@@ -314,6 +244,8 @@ public class MethodsBestiary {
return true; return true;
}else if(creature.getTemplate().getTemplateId() == WyvernWhite.templateId){ }else if(creature.getTemplate().getTemplateId() == WyvernWhite.templateId){
return true; return true;
}else if(creature.getTemplate().getTemplateId() == WyvernBlue.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == Charger.templateId){ }else if(creature.getTemplate().getTemplateId() == Charger.templateId){
return true; return true;
} }
@@ -356,6 +288,8 @@ public class MethodsBestiary {
return 0.5f; return 0.5f;
}else if(templateId == WyvernRed.templateId){ }else if(templateId == WyvernRed.templateId){
return 0.25f; return 0.25f;
}else if(templateId == WyvernBlue.templateId){
return 0.20f;
} }
return -1f; return -1f;
} }

View File

@@ -18,23 +18,22 @@ import com.wurmonline.server.creatures.Creatures;
import com.wurmonline.server.items.*; import com.wurmonline.server.items.*;
import com.wurmonline.server.villages.Village; import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages; import com.wurmonline.server.villages.Villages;
import mod.sin.armour.SpectralHide;
import mod.sin.creatures.Reaper; import mod.sin.creatures.Reaper;
import mod.sin.creatures.SpectralDrake; import mod.sin.creatures.SpectralDrake;
import mod.sin.items.AffinityOrb; import mod.sin.items.AffinityOrb;
import mod.sin.items.ChaosCrystal;
import mod.sin.items.EnchantersCrystal;
import mod.sin.items.FriyanTablet; import mod.sin.items.FriyanTablet;
import mod.sin.items.caches.GemCache; import mod.sin.items.caches.*;
import mod.sin.items.caches.RiftCache;
import mod.sin.items.caches.ToolCache;
import mod.sin.items.caches.TreasureMapCache;
import mod.sin.wyvern.Bounty; import mod.sin.wyvern.Bounty;
import mod.sin.wyvern.MiscChanges; import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.Arena; import mod.sin.wyvern.Arena;
import mod.sin.wyvern.Titans; import mod.sin.wyvern.Titans;
import mod.sin.wyvern.util.ItemUtil; import mod.sin.wyvern.util.ItemUtil;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Logger;
public class LootBounty { public class LootBounty {
public static final Logger logger = Logger.getLogger(LootBounty.class.getName()); public static final Logger logger = Logger.getLogger(LootBounty.class.getName());
protected static final Random random = new Random(); protected static final Random random = new Random();
@@ -108,6 +107,53 @@ public class LootBounty {
return 0; return 0;
} }
public static void insertUniqueLoot(Creature mob, Item corpse){
try {
Item affinityOrb = ItemFactory.createItem(AffinityOrb.templateId, 90+(10*random.nextFloat()), "");
corpse.insertItem(affinityOrb);
int[] cacheIds = {
ArtifactCache.templateId,
CrystalCache.templateId, CrystalCache.templateId,
DragonCache.templateId, DragonCache.templateId,
MoonCache.templateId, MoonCache.templateId,
RiftCache.templateId,
TreasureMapCache.templateId
};
int i = 1+Server.rand.nextInt(3);
while(i > 0){
Item cache = ItemFactory.createItem(cacheIds[Server.rand.nextInt(cacheIds.length)], 50+(30*random.nextFloat()), "");
if(Server.rand.nextInt(5) == 0){
cache.setRarity((byte) 1);
}
corpse.insertItem(cache);
i--;
}
if(mob.isDragon()) {
int mTemplate = mob.getTemplate().getTemplateId();
int lootTemplate = ItemList.drakeHide;
if(mTemplate == CreatureTemplateFactory.DRAGON_BLACK_CID || mTemplate == CreatureTemplateFactory.DRAGON_BLUE_CID || mTemplate == CreatureTemplateFactory.DRAGON_GREEN_CID
|| mTemplate == CreatureTemplateFactory.DRAGON_RED_CID || mTemplate == CreatureTemplateFactory.DRAGON_WHITE_CID){
lootTemplate = ItemList.dragonScale;
}
logger.info("Generating extra hide & scale to insert on the corpse of " + mob.getName() + ".");
ItemTemplate itemTemplate = ItemTemplateFactory.getInstance().getTemplate(lootTemplate);
for (i = 0; i < 2; i++) {
Item loot = ItemFactory.createItem(lootTemplate, 80 + (15 * random.nextFloat()), "");
String creatureName = mob.getTemplate().getName().toLowerCase();
if (!loot.getName().contains(creatureName)) {
loot.setName(creatureName.toLowerCase() + " " + itemTemplate.getName());
}
loot.setData2(mTemplate);
int weightGrams = itemTemplate.getWeightGrams() * (lootTemplate == ItemList.drakeHide ? 3 : 1);
loot.setWeight((int) ((weightGrams * 0.02f) + (weightGrams * 0.02f * random.nextFloat())), true);
corpse.insertItem(loot);
}
}
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
}
public static void blessWorldWithMoonVeins(Creature mob){ public static void blessWorldWithMoonVeins(Creature mob){
int i = 20; int i = 20;
while(i > 0){ while(i > 0){
@@ -290,8 +336,7 @@ public class LootBounty {
if(templateId == Reaper.templateId || templateId == SpectralDrake.templateId){ if(templateId == Reaper.templateId || templateId == SpectralDrake.templateId){
Server.getInstance().broadCastAlert("The "+mob.getName()+" has been slain. A new creature shall enter the realm shortly."); Server.getInstance().broadCastAlert("The "+mob.getName()+" has been slain. A new creature shall enter the realm shortly.");
sendLootHelp = true; sendLootHelp = true;
} }else if(Titans.isTitan(mob)){
else if(Titans.isTitan(mob)){
Server.getInstance().broadCastAlert("The Titan "+mob.getName()+" has been defeated!"); Server.getInstance().broadCastAlert("The Titan "+mob.getName()+" has been defeated!");
MiscChanges.sendGlobalFreedomChat(mob, "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180); MiscChanges.sendGlobalFreedomChat(mob, "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180); MiscChanges.sendServerTabMessage("titan", "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180);
@@ -331,21 +376,9 @@ public class LootBounty {
blessWorldWithMoonVeins(mob); blessWorldWithMoonVeins(mob);
// Spawn 5-10 friyan tablets throughout the world. // Spawn 5-10 friyan tablets throughout the world.
spawnFriyanTablets(); spawnFriyanTablets();
// Add unique loot
insertUniqueLoot(mob, corpse);
try {
// guaranteed rare egg, 15% chance it's fantastic
Item item = ItemFactory.createItem(ItemUtil.getMysteryEggID(), 50, "");
item.setRarity((byte)1);
if(random.nextInt( 100) < 15) {
item.setRarity((byte)3);
}
corpse.insertItem(item);
//free affinity orb
item = ItemFactory.createItem(AffinityOrb.templateId, 50, "");
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
// Spawn Spectral Drake // Spawn Spectral Drake
/*if (mob.isDragon()) { // Spawn the spectral drake and add extra hide/scale /*if (mob.isDragon()) { // Spawn the spectral drake and add extra hide/scale
handleDragonLoot(mob, corpse); handleDragonLoot(mob, corpse);

View File

@@ -83,10 +83,15 @@ public class Mastercraft {
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Special_Title", 553, "Special Guy", "Special Girl", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Special_Title", 553, "Special Guy", "Special Girl", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Prophet_Ear", 554, "Prophet Ear", "Prophet Ear", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Prophet_Ear", 554, "Prophet Ear", "Prophet Ear", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Koza", 555, "Koza", "Koza", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Koza", 555, "Koza", "Koza", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Wyvern_Hunter", 556, "Wyvern Hunter", "Wyvern Hunter", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Overlord", 557, "Overlord", "Overlord", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Troll", 558, "Troll", "Troll", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Beggar", 559, "Beggar", "Beggar", -1, "NORMAL");
// Contest Titles // Contest Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Home_Decorator", 600, "Home Decorator", "Home Decorator", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Home_Decorator", 600, "Home Decorator", "Home Decorator", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Arena_Champion", 601, "Champion of the Arena", "Champion of the Arena", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Arena_Champion", 601, "Champion of the Arena", "Champion of the Arena", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Pastamancer", 602, "Pastamancer", "Pastamancer", -1, "NORMAL");
// Special Event Titles // Special Event Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Titan_Slayer", 700, "Titanslayer", "Titanslayer", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Titan_Slayer", 700, "Titanslayer", "Titanslayer", -1, "NORMAL");
@@ -104,6 +109,8 @@ public class Mastercraft {
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Alexia_TheTreasuring", 806, "The Treasuring", "The Treasuring", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Alexia_TheTreasuring", 806, "The Treasuring", "The Treasuring", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Reevi_ScienceGuy", 807, "Science Guy", "Science Guy", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Reevi_ScienceGuy", 807, "Science Guy", "Science Guy", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Genocide_GrandDesigner", 808, "Grand Designer", "Grand Designer", -1, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("Genocide_GrandDesigner", 808, "Grand Designer", "Grand Designer", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Seleas_CrazyCatLord", 809, "The Crazy Cat Lord", "The Crazy Cat Lord", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Piratemax_Slave", 810, "Slave", "Slave", -1, "NORMAL");
// Characteristic Titles // Characteristic Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("MindLogic_Normal", 1000, "Logical", "Logical", 100, "NORMAL"); ExtendTitleEnum.getSingletonInstance().addExtendEntry("MindLogic_Normal", 1000, "Logical", "Logical", 100, "NORMAL");