Update to latest stable WyvernMods (1.6).

This commit is contained in:
Sindusk
2018-05-03 11:04:10 -04:00
parent 8d4cf4af8d
commit fd333de0ec
83 changed files with 6649 additions and 2656 deletions

View File

@@ -12,8 +12,8 @@ repositories {
dependencies {
compile 'org.gotti.wurmunlimited:server-modlauncher:0.33-beta1'
compile 'com.github.Sindusk:sindusklibrary:v1.0'
compile 'com.github.Sindusk:DiscordRelay:v1.1'
compile 'com.github.Sindusk:sindusklibrary:v1.1'
compile 'com.github.Sindusk:DiscordRelay:v1.2'
compile 'com.github.Sindusk:TreasureHunting:1.1.4'
}

View File

@@ -0,0 +1,6 @@
classname=mod.sin.wyvern.WyvernMods
classpath=WyvernMods.jar
sharedClassLoader=true
depend.import=SinduskLibrary,TreasureHunting,DiscordRelay
#If true, will print debug messages and log heavily.
debug=true

View File

@@ -0,0 +1,93 @@
package com.wurmonline.server.questions;
import com.wurmonline.server.Items;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.deities.Deities;
import com.wurmonline.server.deities.Deity;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.players.Player;
import net.coldie.tools.BmlForm;
import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;
public class BookConversionQuestion extends Question {
protected Item convertBook;
public BookConversionQuestion(Creature aResponder, String aTitle, String aQuestion, long aTarget, Item book){
super(aResponder, aTitle, aQuestion, 79, aTarget);
this.convertBook = book;
}
public static HashMap<Integer, Integer> deityMap = new HashMap<>();
@Override
public void answer(Properties answer) {
boolean accepted = answer.containsKey("accept") && answer.get("accept") == "true";
if (accepted) {
logger.info("Accepted BookOfConversion");
int entry = Integer.parseInt(answer.getProperty("deity"));
int deity = deityMap.get(entry);
if(convertBook == null || convertBook.getOwnerId() != this.getResponder().getWurmId()){
this.getResponder().getCommunicator().sendNormalServerMessage("You must own a book of conversion to begin changing faith.");
}else{
if(this.getResponder() instanceof Player) {
try {
Player p = (Player) this.getResponder();
logger.info("Converting "+p.getName()+" to " + Deities.getDeityName(deity));
Items.destroyItem(convertBook.getWurmId());
Deity d = Deities.getDeity(deity);
p.setDeity(d);
p.setPriest(true);
if(d.hateGod){
p.setAlignment(-Math.abs(p.getAlignment()));
}else{
p.setAlignment(Math.abs(p.getAlignment()));
}
p.setFaith(p.getFaith()*0.9f);
p.getCommunicator().sendAlertServerMessage(Deities.getDeityName(deity)+" accepts your conversion.");
} catch (IOException e) {
e.printStackTrace();
}
}else{
logger.info("Non-player used a "+convertBook.getName()+"?");
}
}
}
}
public static String getDeityNames(){
String builder = "";
int i = 0;
Deity[] deities = Deities.getDeities();
while(i < deities.length){
builder = builder + deities[i].getName();
deityMap.put(i, deities[i].getNumber());
i++;
if(i < deities.length){
builder = builder + ",";
}
}
return builder;
}
@Override
public void sendQuestion() {
if(convertBook == null || convertBook.getOwnerId() != this.getResponder().getWurmId()){
this.getResponder().getCommunicator().sendNormalServerMessage("You must own a book of conversion to begin changing faith.");
return;
}
BmlForm f = new BmlForm("");
f.addHidden("id", String.valueOf(this.id));
f.addBoldText("Select the deity you would like to convert to\nAccepting this will reduce your faith by 10 percent\n", new String[0]);
f.addRaw("harray{label{text='Select New Deity:'}dropdown{id='deity';options='");
f.addRaw(getDeityNames());
f.addRaw("'}}");
f.addText("\n\n", new String[0]);
f.beginHorizontalFlow();
f.addButton("Accept", "accept");
f.endHorizontalFlow();
this.getResponder().getCommunicator().sendBml(400, 300, true, true, f.toString(), 255, 255, 255, this.title);
}
}

View File

@@ -0,0 +1,238 @@
package com.wurmonline.server.questions;
import com.wurmonline.server.DbConnector;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.skills.SkillSystem;
import com.wurmonline.server.utils.DbUtilities;
import net.coldie.tools.BmlForm;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
public class LeaderboardCustomQuestion extends Question {
protected int entryNum;
public LeaderboardCustomQuestion(Creature aResponder, String aTitle, String aQuestion, long aTarget, int entryNum){
super(aResponder, aTitle, aQuestion, 79, aTarget);
this.entryNum = entryNum;
}
@Override
public void answer(Properties answer) {
boolean accepted = answer.containsKey("okay") && answer.get("okay") == "true";
if (accepted) {
LeaderboardQuestion lbq = new LeaderboardQuestion(this.getResponder(), "Leaderboard", "Which leaderboard would you like to view?", this.getResponder().getWurmId());
lbq.sendQuestion();
}
}
protected HashMap<String, Integer> optIn = new HashMap<>();
protected void identifyOptIn(){
String name;
int opted;
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM LeaderboardOpt");
rs = ps.executeQuery();
while (rs.next()) {
name = rs.getString("name");
opted = rs.getInt("OPTIN");
optIn.put(name, opted);
}
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
protected ArrayList<String> names = new ArrayList<>();
protected ArrayList<Double> values = new ArrayList<>();
protected ArrayList<String> extra = new ArrayList<>();
protected void totalSkills(int limit){
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
String name;
int skillNum;
double skill;
try {
dbcon = DbConnector.getPlayerDbCon();
ps = dbcon.prepareStatement("SELECT players.name, achievements.counter FROM achievements JOIN players ON achievements.player = players.wurmid WHERE achievements.achievement = 371 AND players.power = 0 ORDER BY achievements.counter DESC LIMIT "+limit);
rs = ps.executeQuery();
while(rs.next()){
name = rs.getString(1);
skill = rs.getDouble(2);
names.add(name);
values.add(skill);
}
DbUtilities.closeDatabaseObjects(ps, rs);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
protected void topAnySkill(int limit){
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
String name;
int skillNum;
double skill;
try {
dbcon = DbConnector.getPlayerDbCon();
ps = dbcon.prepareStatement("SELECT players.name, skills.number, skills.value FROM skills JOIN players ON skills.owner = players.wurmid WHERE players.power = 0 ORDER BY skills.value DESC LIMIT "+limit);
rs = ps.executeQuery();
while(rs.next()){
name = rs.getString(1);
skillNum = rs.getInt(2);
skill = rs.getDouble(3);
names.add(name);
values.add(skill);
extra.add(SkillSystem.getNameFor(skillNum));
}
DbUtilities.closeDatabaseObjects(ps, rs);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
//select wurmid, count(*) from titles group by wurmid order by count(*) desc;
protected void totalTitles(int limit){
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
String name;
int skillNum;
double skill;
try {
dbcon = DbConnector.getPlayerDbCon();
ps = dbcon.prepareStatement("SELECT players.name, COUNT(titles.wurmid) as Count FROM titles JOIN players ON titles.wurmid = players.wurmid WHERE players.power = 0 GROUP BY titles.wurmid ORDER BY Count DESC LIMIT "+limit);
rs = ps.executeQuery();
while(rs.next()){
name = rs.getString(1);
skill = rs.getDouble(2);
names.add(name);
values.add(skill);
}
DbUtilities.closeDatabaseObjects(ps, rs);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
protected void topPlayerStats(String statName, int limit){
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
String name;
int skillNum;
double stat;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT name, "+statName+" FROM PlayerStats ORDER BY "+statName+" DESC LIMIT "+limit);
rs = ps.executeQuery();
while(rs.next()){
name = rs.getString(1);
stat = rs.getDouble(2);
names.add(name);
values.add(stat);
}
DbUtilities.closeDatabaseObjects(ps, rs);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void sendQuestion() {
BmlForm f = new BmlForm("");
f.addHidden("id", String.valueOf(this.id));
// Populates HashMap with latest opt-in data.
identifyOptIn();
// Identify and execute correct list generation.
boolean format = false;
boolean ignoreOpt = false;
int limit = 20;
switch(entryNum){
case 0:
limit = 50;
totalSkills(limit);
break;
case 1:
limit = 50;
topAnySkill(limit);
format = true;
break;
case 2:
limit = 50;
totalTitles(limit);
break;
case 3:
limit = 10;
topPlayerStats("kills", limit);
ignoreOpt = true;
break;
case 4:
limit = 10;
topPlayerStats("deaths", limit);
ignoreOpt = true;
break;
case 5:
limit = 10;
topPlayerStats("depots", limit);
ignoreOpt = true;
break;
}
f.addBoldText("Top "+limit+" players in "+this.getQuestion(), new String[0]);
f.addText("\n\n", new String[0]);
int i = 0;
DecimalFormat df = new DecimalFormat(".000");
if(!format){
df = new DecimalFormat("#");
}
String name;
String line;
while(i < names.size() && i < values.size()){
name = names.get(i);
if(!ignoreOpt) {
if (!optIn.containsKey(name)) {
name = "Unknown";
} else if (optIn.get(name).equals(0)) {
name = "Unknown";
}
}
line = df.format(values.get(i)) + " - " + name;
if(extra.size() >= i+1){
line = line + " ("+ extra.get(i)+")";
}
if(names.get(i).equals(this.getResponder().getName())){
f.addBoldText(line);
}else{
f.addText(line);
}
i++;
}
f.addText(" \n", new String[0]);
f.beginHorizontalFlow();
f.addButton("Ok", "okay");
f.endHorizontalFlow();
f.addText(" \n", new String[0]);
this.getResponder().getCommunicator().sendBml(400, 500, true, true, f.toString(), 150, 150, 200, this.title);
}
}

View File

@@ -0,0 +1,157 @@
package com.wurmonline.server.questions;
import com.wurmonline.server.Servers;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.skills.SkillSystem;
import com.wurmonline.server.skills.SkillTemplate;
import net.coldie.tools.BmlForm;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Properties;
public class LeaderboardQuestion extends Question {
public LeaderboardQuestion(Creature aResponder, String aTitle, String aQuestion, long aTarget){
super(aResponder, aTitle, aQuestion, 79, aTarget);
}
protected void setPlayerOptStatus(String name, int opt){
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("UPDATE LeaderboardOpt SET OPTIN = " + opt + " WHERE name = \"" + name + "\"");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void answer(Properties answer) {
boolean accepted = answer.containsKey("accept") && answer.get("accept") == "true";
boolean custom = answer.containsKey("custom") && answer.get("custom") == "true";
if (accepted) {
int entry = Integer.parseInt(answer.getProperty("leaderboard"));
String val = skillMap.get(entry);
int skillNum = skillIdMap.get(entry);
//this.getResponder().getCommunicator().sendNormalServerMessage("Received response: "+val);
LeaderboardSkillQuestion lbsq = new LeaderboardSkillQuestion(this.getResponder(), "Leaderboard", val, this.getResponder().getWurmId(), skillNum);
lbsq.sendQuestion();
}else if(custom){
int entry = Integer.parseInt(answer.getProperty("customboard"));
String val = customMap.get(entry);
LeaderboardCustomQuestion lbcq = new LeaderboardCustomQuestion(this.getResponder(), "Leaderboard", val, this.getResponder().getWurmId(), entry);
lbcq.sendQuestion();
}else{
String name = this.getResponder().getName();
if(answer.containsKey("optin") && answer.get("optin") == "true"){
logger.info("Player "+name+" has opted into Leaderboard system.");
setPlayerOptStatus(name, 1);
this.getResponder().getCommunicator().sendNormalServerMessage("You have opted into the Leaderboard system!");
}else if(answer.containsKey("optout") && answer.get("optout") == "true"){
logger.info("Player "+name+" has opted out of the Leaderboard system.");
setPlayerOptStatus(name, 0);
this.getResponder().getCommunicator().sendNormalServerMessage("You have opted out of the Leaderboard system.");
}
}
}
protected HashMap<Integer, String> skillMap = new HashMap<>();
protected HashMap<Integer, Integer> skillIdMap = new HashMap<>();
protected HashMap<Integer, String> customMap = new HashMap<>();
public String getSkillOptions(){
String builder = "";
SkillTemplate[] skillTemplates = SkillSystem.getAllSkillTemplates();
Arrays.sort(skillTemplates, new Comparator<SkillTemplate>(){
public int compare(SkillTemplate o1, SkillTemplate o2){
return o1.getName().compareTo(o2.getName());
}
});
int i = 0;
int index = 0;
skillMap.clear();
while(i < skillTemplates.length){
builder = builder + skillTemplates[i].getName();
skillMap.put(index, skillTemplates[i].getName());
skillIdMap.put(index, skillTemplates[i].getNumber());
i++;
index++;
if(i < skillTemplates.length){
builder = builder + ",";
}
}
return builder;
}
public String getCustomOptions(){
String builder = "Total Skill";
customMap.put(0, "Total Skill");
builder = builder + ",High Skills";
customMap.put(1, "High Skills");
builder = builder + ",Most Titles";
customMap.put(2, "Most Titles");
if(Servers.localServer.PVPSERVER || this.getResponder().getPower() >= 5){
builder = builder + ",PvP Kills";
customMap.put(3, "PvP Kills");
builder = builder + ",PvP Deaths";
customMap.put(4, "PvP Deaths");
builder = builder + ",Depots Captured";
customMap.put(5, "PvP Depots Captured");
}
return builder;
}
@Override
public void sendQuestion() {
BmlForm f = new BmlForm("");
f.addHidden("id", String.valueOf(this.id));
int opted;
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM LeaderboardOpt WHERE name = \"" + this.getResponder().getName() + "\"");
rs = ps.executeQuery();
opted = rs.getInt("OPTIN");
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
f.addBoldText("You are currently " + (opted == 0 ? "not " : "") + "opted into the leaderboard system.\n\n", new String[0]);
f.addRaw("harray{label{text='View leaderboard:'}dropdown{id='leaderboard';options='");
f.addRaw(getSkillOptions());
f.addRaw("'}}");
f.beginHorizontalFlow();
f.addButton("Accept", "accept");
f.endHorizontalFlow();
f.addText(" \n\n", new String[0]);
f.addBoldText("Opt into or out of the Leaderboard system.");
f.beginHorizontalFlow();
f.addButton("Opt In", "optin");
f.addButton("Opt Out", "optout");
f.endHorizontalFlow();
f.addText(" \n\n", new String[0]);
f.addBoldText("Special leaderboards are available below.");
f.addRaw("harray{label{text='View leaderboard:'}dropdown{id='customboard';options='");
f.addRaw(getCustomOptions());
f.addRaw("'}}");
f.beginHorizontalFlow();
f.addButton("Accept", "custom");
f.endHorizontalFlow();
this.getResponder().getCommunicator().sendBml(400, 500, true, true, f.toString(), 150, 150, 200, this.title);
}
}

View File

@@ -0,0 +1,127 @@
package com.wurmonline.server.questions;
import com.wurmonline.server.DbConnector;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.deities.Deities;
import com.wurmonline.server.skills.SkillList;
import com.wurmonline.server.skills.SkillSystem;
import com.wurmonline.server.skills.SkillTemplate;
import com.wurmonline.server.utils.DbUtilities;
import net.coldie.tools.BmlForm;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
public class LeaderboardSkillQuestion extends Question {
protected int skillNum;
public LeaderboardSkillQuestion(Creature aResponder, String aTitle, String aQuestion, long aTarget, int skillNum){
super(aResponder, aTitle, aQuestion, 79, aTarget);
this.skillNum = skillNum;
}
@Override
public void answer(Properties answer) {
boolean accepted = answer.containsKey("okay") && answer.get("okay") == "true";
if (accepted) {
LeaderboardQuestion lbq = new LeaderboardQuestion(this.getResponder(), "Leaderboard", "Which leaderboard would you like to view?", this.getResponder().getWurmId());
lbq.sendQuestion();
}
}
protected HashMap<String, Integer> optIn = new HashMap<>();
protected void identifyOptIn(){
String name;
int opted;
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM LeaderboardOpt");
rs = ps.executeQuery();
while (rs.next()) {
name = rs.getString("name");
opted = rs.getInt("OPTIN");
optIn.put(name, opted);
}
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void sendQuestion() {
BmlForm f = new BmlForm("");
f.addHidden("id", String.valueOf(this.id));
ArrayList<String> names = new ArrayList<>();
ArrayList<Double> skills = new ArrayList<>();
ArrayList<Integer> deities = new ArrayList<>();
String name;
double skill;
int deity;
String extra = "";
// Populates HashMap with latest opt-in data.
identifyOptIn();
Connection dbcon;
PreparedStatement ps;
ResultSet rs;
try {
dbcon = DbConnector.getPlayerDbCon();
ps = dbcon.prepareStatement("SELECT players.name, skills.value, players.deity FROM skills JOIN players ON skills.owner = players.wurmid WHERE skills.number = " + skillNum + " AND (players.power = 0) ORDER BY skills.value DESC LIMIT 20");
rs = ps.executeQuery();
while(rs.next()){
name = rs.getString(1);
skill = rs.getDouble(2);
deity = rs.getInt(3);
names.add(name);
skills.add(skill);
deities.add(deity);
}
DbUtilities.closeDatabaseObjects(ps, rs);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
f.addBoldText("Top 20 players in "+this.getQuestion(), new String[0]);
f.addText("\n\n", new String[0]);
int i = 0;
DecimalFormat df = new DecimalFormat(".000");
while(i < names.size() && i < skills.size()){
name = names.get(i);
if(!optIn.containsKey(name)){
name = "Unknown";
}else if(optIn.get(name).equals(0)){
name = "Unknown";
}
if(skillNum == SkillList.CHANNELING){
extra = " ("+ Deities.getDeityName(deities.get(i))+")";
}
if(names.get(i).equals(this.getResponder().getName())){
name = names.get(i);
f.addBoldText(df.format(skills.get(i)) + " - " + name + extra);
}else{
f.addText(df.format(skills.get(i)) + " - " + name + extra);
}
i++;
}
f.addText(" \n", new String[0]);
f.beginHorizontalFlow();
f.addButton("Ok", "okay");
f.endHorizontalFlow();
f.addText(" \n", new String[0]);
this.getResponder().getCommunicator().sendBml(400, 500, true, true, f.toString(), 150, 150, 200, this.title);
}
}

View File

@@ -0,0 +1,146 @@
package com.wurmonline.server.questions;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.*;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.players.Spawnpoint;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import net.coldie.tools.BmlForm;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Properties;
public class NewSpawnQuestion extends Question {
public NewSpawnQuestion(Creature aResponder, String aTitle, String aQuestion, long aTarget){
super(aResponder, aTitle, aQuestion, 79, aTarget);
}
public void spawn(Player p, Spawnpoint spawnpoint) {
if (p.isDead()) {
p.addNewbieBuffs();
p.setLayer(0, false);
boolean found = false;
if (p.isUndead()) {
float[] txty = Player.findRandomSpawnX(false, false);
float posX = txty[0];
float posY = txty[1];
p.setTeleportPoints(posX, posY, 0, 0);
p.startTeleporting();
p.getCommunicator().sendNormalServerMessage("You are cast back into the horrible light.");
} else {
p.setTeleportPoints(spawnpoint.tilex, spawnpoint.tiley, spawnpoint.surfaced ? 0 : -1, 0);
p.startTeleporting();
p.getCommunicator().sendNormalServerMessage("You are cast back into the light.");
}
p.getCommunicator().sendTeleport(false);
try { //p.setDead(false);
ReflectionUtil.callPrivateMethod(p, ReflectionUtil.getMethod(p.getClass(), "setDead"), false);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
p.spawnpoints = null;
}
}
@Override
public void answer(Properties answer) {
boolean accepted = answer.containsKey("accept") && answer.get("accept") == "true";
if (accepted) {
logger.info("Accepted NewSpawnQuestion");
int entry = Integer.parseInt(answer.getProperty("spawnpoint"));
Spawnpoint spawn = spawns.get(entry);
this.spawn((Player) this.getResponder(), spawn);
}else{
boolean transfer = answer.containsKey("transfer") && answer.get("transfer") == "true";
if(transfer) {
try {
ServerEntry targetServer = Servers.localServer.serverSouth;
Player player = Players.getInstance().getPlayer(this.getResponder().getWurmId());
if(targetServer == null){
player.getCommunicator().sendNormalServerMessage("Error: Something went wrong [TARGETSERVER=NULL].");
}
if (!targetServer.isAvailable(player.getPower(), true)) {
player.getCommunicator().sendNormalServerMessage(targetServer.name + " is not currently available.");
} else {
player.sendTransfer(Server.getInstance(), targetServer.EXTERNALIP, Integer.parseInt(targetServer.EXTERNALPORT), targetServer.INTRASERVERPASSWORD, targetServer.getId(), -1, -1, true, false, player.getKingdomId());
}
} catch (NoSuchPlayerException e) {
logger.info("Could not find player for WurmId " + this.getResponder().getWurmId() + " [" + this.getResponder().getName() + "]");
e.printStackTrace();
}
}else {
this.getResponder().getCommunicator().sendNormalServerMessage("You can bring the spawn question back by typing /respawn in a chat window.");
}
}
}
protected static HashMap<Integer, Spawnpoint> spawns = new HashMap<>();
public Spawnpoint getRandomSpawnpoint(byte spawnNums){
int i = 1000;
while(i > 0){
i--;
int x = Server.rand.nextInt(Server.surfaceMesh.getSize());
int y = Server.rand.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
if(height > 0 && height < 1000 && Creature.getTileSteepness(x, y, true)[1] < 30){
Village v = Villages.getVillage(x, y, true);
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
}
}
if(v != null){
continue;
}
return new Spawnpoint(spawnNums, "Random location", (short) x, (short) y, true);
}
}
return null;
}
public String getSpawnpointOptions(){
String builder = "";
byte spawnNums = 0;
if(this.getResponder().citizenVillage != null){
Village v = this.getResponder().citizenVillage;
short tpx = (short)v.getTokenX();
short tpy = (short)v.getTokenY();
Spawnpoint home = new Spawnpoint(spawnNums, "Token of " + v.getName(), tpx, tpy, v.isOnSurface());
spawns.put((int) spawnNums, home);
builder += home.description+",";
spawnNums++;
}
Spawnpoint random = getRandomSpawnpoint(spawnNums);
spawns.put((int) spawnNums, random);
builder += random.description;
return builder;
}
@Override
public void sendQuestion() {
BmlForm f = new BmlForm("");
f.addHidden("id", String.valueOf(this.id));
f.addBoldText("Where would you like to spawn?\n\n", new String[0]);
f.addText("\n\n", new String[0]);
f.addRaw("harray{label{text='Respawn Point:'}dropdown{id='spawnpoint';options='");
f.addRaw(getSpawnpointOptions());
f.addRaw("'}}");
f.addText("\n\n", new String[0]);
f.beginHorizontalFlow();
f.addButton("Accept", "accept");
f.endHorizontalFlow();
f.addText("\n\n", new String[0]);
f.addBoldText("Or transfer back to the PvE server:");
f.addText("\n\n", new String[0]);
f.beginHorizontalFlow();
f.addButton("Transfer to PvE", "transfer");
f.endHorizontalFlow();
this.getResponder().getCommunicator().sendBml(400, 300, true, true, f.toString(), 128, 50, 50, this.title);
}
}

View File

@@ -1,14 +1,5 @@
package mod.sin.actions;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
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 com.wurmonline.server.Server;
import com.wurmonline.server.ServerEntry;
import com.wurmonline.server.Servers;
@@ -18,6 +9,15 @@ import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.players.Player;
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.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ArenaEscapeAction implements ModAction {
private static Logger logger = Logger.getLogger(ArenaEscapeAction.class.getName());
@@ -55,7 +55,7 @@ public class ArenaEscapeAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && (object.getTemplateId() == ItemList.bodyBody || object.getTemplateId() == ItemList.bodyHand) && Servers.localServer.PVPSERVER) {
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;
@@ -93,10 +93,10 @@ public class ArenaEscapeAction implements ModAction {
}
if(counter == 1.0f){
performer.getCommunicator().sendNormalServerMessage("You prepare your body and mind to transfer to another realm.");
act.setTimeLeft(1200);
act.setTimeLeft(1800);
performer.sendActionControl("Preparing", true, act.getTimeLeft());
}else if(counter * 10f > performer.getCurrentAction().getTimeLeft()){
ServerEntry targetserver = Servers.localServer.serverWest;
ServerEntry targetserver = Servers.localServer.serverSouth;
if(targetserver == null){
performer.getCommunicator().sendNormalServerMessage("Error: Something went wrong [TARGETSERVER=NULL].");
return true;
@@ -108,8 +108,8 @@ public class ArenaEscapeAction implements ModAction {
performer.getCommunicator().sendNormalServerMessage("You successfully escape the arena.");
performer.getCommunicator().sendNormalServerMessage("You transfer to " + targetserver.name + ".");
Server.getInstance().broadCastAction(performer.getName() + " transfers to " + targetserver.name + ".", performer, 5);
int tilex = targetserver.SPAWNPOINTJENNX;
int tiley = targetserver.SPAWNPOINTJENNY;
int tilex = 1010;
int tiley = 1010;
((Player)performer).sendTransfer(Server.getInstance(), targetserver.INTRASERVERADDRESS, Integer.parseInt(targetserver.INTRASERVERPORT), targetserver.INTRASERVERPASSWORD, targetserver.id, tilex, tiley, true, false, performer.getKingdomId());
((Player)performer).transferCounter = 30;
return true;

View File

@@ -1,6 +1,7 @@
package mod.sin.actions;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -54,8 +55,8 @@ public class ArenaTeleportAction implements ModAction {
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && (object.getTemplateId() == ItemList.bodyBody || object.getTemplateId() == ItemList.bodyHand) && Servers.localServer.id == 567) {
return Arrays.asList(actionEntry);
if(performer instanceof Player && object != null && (object.getTemplateId() == ItemList.bodyBody || object.getTemplateId() == ItemList.bodyHand) && !Servers.localServer.PVPSERVER) {
return Collections.singletonList(actionEntry);
}
return null;
@@ -79,7 +80,7 @@ public class ArenaTeleportAction implements ModAction {
{
try{
if(performer instanceof Player){
if(Servers.localServer.id != 567){
if(Servers.localServer.PVPSERVER){
performer.getCommunicator().sendNormalServerMessage("You cannot enter the arena from here.");
return true;
}
@@ -98,7 +99,7 @@ public class ArenaTeleportAction implements ModAction {
}else if(act.currentSecond() == 55){
performer.getCommunicator().sendNormalServerMessage("It appears you have accepted these conditions. Transferring to the arena. Good luck.", (byte) 3);
}else if(counter * 10f > performer.getCurrentAction().getTimeLeft()){
ServerEntry targetserver = Servers.localServer.serverEast;
ServerEntry targetserver = Servers.localServer.serverNorth;
if(targetserver == null){
performer.getCommunicator().sendNormalServerMessage("Error: Something went wrong [TARGETSERVER=NULL].");
return true;
@@ -109,8 +110,8 @@ public class ArenaTeleportAction implements ModAction {
}
performer.getCommunicator().sendNormalServerMessage("You transfer to " + targetserver.name + ".");
Server.getInstance().broadCastAction(performer.getName() + " transfers to " + targetserver.name + ".", performer, 5);
int tilex = 128+Server.rand.nextInt(768);
int tiley = 128+Server.rand.nextInt(768);
int tilex = 1010;
int tiley = 1010;
((Player)performer).sendTransfer(Server.getInstance(), targetserver.INTRASERVERADDRESS, Integer.parseInt(targetserver.INTRASERVERPORT), targetserver.INTRASERVERPASSWORD, targetserver.id, tilex, tiley, true, false, performer.getKingdomId());
((Player)performer).transferCounter = 30;
return true;

View File

@@ -0,0 +1,100 @@
package mod.sin.actions;
import com.wurmonline.server.Servers;
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.ItemList;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.questions.LeaderboardQuestion;
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.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LeaderboardAction implements ModAction {
private static Logger logger = Logger.getLogger(LeaderboardAction.class.getName());
private final short actionId;
private final ActionEntry actionEntry;
public LeaderboardAction() {
logger.log(Level.WARNING, "LeaderboardAction()");
actionId = (short) ModActions.getNextActionId();
actionEntry = ActionEntry.createEntry(
actionId,
"Leaderboard",
"leaderboarding",
new int[] { 0 } // 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)
{
return this.getBehavioursFor(performer, object);
}
// Menu without activated object
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && (object.getTemplateId() == ItemList.bodyBody || object.getTemplateId() == ItemList.bodyHand)) {
return Collections.singletonList(actionEntry);
}
return null;
}
};
}
@Override
public ActionPerformer getActionPerformer()
{
return new ActionPerformer() {
@Override
public short getActionId() {
return actionId;
}
// Without activated object
@Override
public boolean action(Action act, Creature performer, Item target, short action, float counter)
{
try{
if(performer instanceof Player){
LeaderboardQuestion lbq = new LeaderboardQuestion(performer, "Leaderboard", "Which leaderboard would you like to view?", performer.getWurmId());
lbq.sendQuestion();
}
return true;
}catch(Exception e){
e.printStackTrace();
return true;
}
}
@Override
public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter)
{
return this.action(act, performer, target, action, counter);
}
}; // ActionPerformer
}
}

View File

@@ -0,0 +1,134 @@
package mod.sin.actions;
import com.wurmonline.server.NoSuchItemException;
import com.wurmonline.server.Server;
import com.wurmonline.server.behaviours.Action;
import com.wurmonline.server.behaviours.ActionEntry;
import com.wurmonline.server.behaviours.AutoEquipMethods;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.deities.Deities;
import com.wurmonline.server.epic.EpicServerStatus;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.players.Player;
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.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MissionAction implements ModAction {
private static Logger logger = Logger.getLogger(MissionAction.class.getName());
private final short actionId;
private final ActionEntry actionEntry;
public MissionAction() {
logger.log(Level.WARNING, "UnequipAllAction()");
actionId = (short) ModActions.getNextActionId();
actionEntry = ActionEntry.createEntry(
actionId,
"Generate Epic Mission",
"generating",
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)
{
return this.getBehavioursFor(performer, object);
}
// Menu without activated object
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && (object.getTemplateId() == ItemList.bodyBody || object.getTemplateId() == ItemList.bodyHand) && performer.getPower() >= 5) {
return Collections.singletonList(actionEntry);
}
return null;
}
};
}
@Override
public ActionPerformer getActionPerformer()
{
return new ActionPerformer() {
@Override
public short getActionId() {
return actionId;
}
// Without activated object
@Override
public boolean action(Action act, Creature performer, Item target, short action, float counter)
{
if(performer instanceof Player){
Player player = (Player) performer;
int[] deityNums = {
1, 2, 3, 4, // Original Gods
6, 7, 8, 9, 10, 11, 12 // Valrei Entities
};
if(EpicServerStatus.getCurrentEpicMissions().length >= deityNums.length){
logger.info("All entities already have a mission. Aborting.");
return true;
}
int i = 10;
int number = 1;
while(i > 0) {
number = deityNums[Server.rand.nextInt(deityNums.length)];
logger.info("Testing number "+number);
if(EpicServerStatus.getEpicMissionForEntity(number) == null){
logger.info("Has no mission, breaking loop.");
break;
}else{
logger.info("Has mission, finding new number.");
}
i++;
if(i == 0){
logger.info("Ran through 10 possible entities and could not find empty mission. Cancelling.");
return true;
}
}
logger.info("Entity number = "+number);
String entityName = Deities.getDeityName(number);
logger.info("Entity name = "+entityName);
int time = 604800;
logger.info("Current epic missions: "+EpicServerStatus.getCurrentEpicMissions().length);
EpicServerStatus es = new EpicServerStatus();
if (EpicServerStatus.getCurrentScenario() != null) {
es.generateNewMissionForEpicEntity(number, entityName, -1, time, EpicServerStatus.getCurrentScenario().getScenarioName(), EpicServerStatus.getCurrentScenario().getScenarioNumber(), EpicServerStatus.getCurrentScenario().getScenarioQuest(), true);
}
}else{
logger.info("Somehow a non-player activated an Affinity Orb...");
}
return true;
}
@Override
public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter)
{
return this.action(act, performer, target, action, counter);
}
}; // ActionPerformer
}
}

View File

@@ -0,0 +1,163 @@
package mod.sin.actions;
import com.wurmonline.server.Items;
import com.wurmonline.server.Server;
import com.wurmonline.server.Servers;
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.players.Player;
import mod.sin.items.SorceryFragment;
import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.util.ItemUtil;
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.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SorceryCombineAction implements ModAction {
private static Logger logger = Logger.getLogger(SorceryCombineAction.class.getName());
private final short actionId;
private final ActionEntry actionEntry;
public SorceryCombineAction() {
logger.log(Level.WARNING, "ArenaTeleport()");
actionId = (short) ModActions.getNextActionId();
actionEntry = ActionEntry.createEntry(
actionId,
"Combine sorcery",
"combining sorcery",
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)
{
return this.getBehavioursFor(performer, object);
}
// Menu without activated object
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && object.isHugeAltar() && Servers.localServer.PVPSERVER) {
return Collections.singletonList(actionEntry);
}
return null;
}
};
}
@Override
public ActionPerformer getActionPerformer()
{
return new ActionPerformer() {
@Override
public short getActionId() {
return actionId;
}
// Without activated object
@Override
public boolean action(Action act, Creature performer, Item target, short action, float counter)
{
try{
if(performer instanceof Player){
if(!target.isHugeAltar()){
performer.getCommunicator().sendNormalServerMessage("You must combine at a huge altar.");
return true;
}
int fragments = 0;
Set<Item> inventory = performer.getInventory().getItems();
for(Item i : inventory){
if(i.getTemplateId() == SorceryFragment.templateId){
fragments++;
}
}
if(fragments < 2){
performer.getCommunicator().sendNormalServerMessage("You must have at least two sorcery fragments to combine.");
return true;
}
if(counter == 1.0f){
performer.getCommunicator().sendSafeServerMessage("You begin to combine sorcery fragments.");
MiscChanges.sendServerTabMessage("arena", performer.getName()+" is beginning to combine sorcery fragments at the "+target.getName()+"!", 52, 152, 219);
act.setTimeLeft(3000);
performer.sendActionControl("Combining sorcery", true, act.getTimeLeft());
}else if(counter * 10f > performer.getCurrentAction().getTimeLeft()){
Set<Item> items = performer.getInventory().getItems();
Item first = null;
Item second = null;
for(Item i : items){
if(i.getTemplateId() == SorceryFragment.templateId){
if(first == null){
first = i;
}else if(second == null){
second = i;
}
}
}
if(first == null || second == null){
performer.getCommunicator().sendNormalServerMessage("Something went wrong with the combination.");
return true;
}
byte firstAux = first.getAuxData();
byte secondAux = (byte) (second.getAuxData()+1);
if(firstAux + secondAux >= 9){
byte newAux = (byte) (firstAux+secondAux-10);
performer.getCommunicator().sendSafeServerMessage("A new sorcery has been created!");
MiscChanges.sendServerTabMessage("arena", performer.getName()+" has created a new sorcery!", 52, 152, 219);
Item sorcery = ItemUtil.createRandomSorcery((byte) (2+Server.rand.nextInt(1)));
logger.info("Player "+performer.getName()+" created a "+sorcery.getName()+" with "+(3-sorcery.getAuxData())+" charges.");
performer.getInventory().insertItem(sorcery, true);
if(newAux >= 0) {
first.setAuxData(newAux);
first.setName("sorcery fragment [" + (first.getAuxData() + 1) + "/10]");
}else{
Items.destroyItem(first.getWurmId());
}
}else{
performer.getCommunicator().sendSafeServerMessage("You combine fragments.");
MiscChanges.sendServerTabMessage("arena", performer.getName()+" has combined sorcery fragments, and is closer to creating a new sorcery.", 52, 152, 219);
first.setAuxData((byte) (firstAux+secondAux));
first.setName("sorcery fragment ["+(first.getAuxData()+1)+"/10]");
}
Items.destroyItem(second.getWurmId());
return true;
}
}
return false;
}catch(Exception e){
e.printStackTrace();
return true;
}
}
@Override
public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter)
{
return this.action(act, performer, target, action, counter);
}
}; // ActionPerformer
}
}

View File

@@ -1,6 +1,7 @@
package mod.sin.actions;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -32,7 +33,7 @@ public class UnequipAllAction implements ModAction {
actionId,
"Unequip all armour",
"unequipping",
new int[0]
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);
@@ -56,7 +57,7 @@ public class UnequipAllAction implements ModAction {
{
try {
if(performer instanceof Player && object != null && object.getParentOrNull() != null && object.getParent().isBodyPart() && object.getParent().getOwnerId() == performer.getWurmId()) {
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
} catch (NoSuchItemException e) {
e.printStackTrace();
@@ -93,7 +94,7 @@ public class UnequipAllAction implements ModAction {
return true;
}
for(Item equip : player.getBody().getAllItems()){
if(equip.isArmour()){
if(equip.isArmour() && equip.getParent().getWurmId() != player.getBody().getId()){
AutoEquipMethods.unequip(equip, player);
}
}

View File

@@ -1,15 +1,5 @@
package mod.sin.actions.items;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
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 com.wurmonline.server.Items;
import com.wurmonline.server.behaviours.Action;
import com.wurmonline.server.behaviours.ActionEntry;
@@ -19,8 +9,16 @@ import com.wurmonline.server.players.Player;
import com.wurmonline.server.skills.Affinities;
import com.wurmonline.server.skills.Affinity;
import com.wurmonline.server.skills.SkillSystem;
import mod.sin.items.AffinityOrb;
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.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AffinityOrbAction implements ModAction {
private static Logger logger = Logger.getLogger(AffinityOrbAction.class.getName());
@@ -58,7 +56,7 @@ public class AffinityOrbAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && object.getTemplateId() == AffinityOrb.templateId) {
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;

View File

@@ -1,15 +1,5 @@
package mod.sin.actions.items;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
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 com.wurmonline.server.Items;
import com.wurmonline.server.Server;
import com.wurmonline.server.behaviours.Action;
@@ -17,9 +7,17 @@ import com.wurmonline.server.behaviours.ActionEntry;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.players.Player;
import mod.sin.items.ArenaCache;
import mod.sin.wyvern.arena.SupplyDepots;
import mod.sin.wyvern.SupplyDepots;
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.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ArenaCacheOpenAction implements ModAction {
private static Logger logger = Logger.getLogger(ArenaCacheOpenAction.class.getName());
@@ -57,7 +55,7 @@ public class ArenaCacheOpenAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && object.getTemplateId() == ArenaCache.templateId) {
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;

View File

@@ -1,6 +1,7 @@
package mod.sin.actions.items;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
@@ -62,7 +63,7 @@ public class ArrowPackUnpackAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && (object.getTemplateId() == ArrowPackHunting.templateId || object.getTemplateId() == ArrowPackWar.templateId)) {
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;
@@ -108,7 +109,7 @@ public class ArrowPackUnpackAction implements ModAction {
if(target.getRarity() > 0){
quality = Math.min(100f, target.getCurrentQualityLevel()+target.getRarity());
}
HashMap<Byte, Float> spellEffects = new HashMap<Byte, Float>();
HashMap<Byte, Float> spellEffects = new HashMap<>();
ItemSpellEffects effs = target.getSpellEffects();
if(effs != null){
for(SpellEffect eff : effs.getEffects()){
@@ -123,6 +124,7 @@ public class ArrowPackUnpackAction implements ModAction {
int i = 0;
while(i < 40){
arrow = ItemFactory.createItem(arrowTemplate, quality, performer.getName());
arrow.setMaterial(target.getMaterial());
arrow.setRarity(target.getRarity());
if(!spellEffects.isEmpty()){
for(byte b : spellEffects.keySet()){

View File

@@ -0,0 +1,94 @@
package mod.sin.actions.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.players.Player;
import com.wurmonline.server.questions.BookConversionQuestion;
import mod.sin.items.BookOfConversion;
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.util.Collections;
import java.util.List;
import java.util.logging.Logger;
public class BookConversionAction implements ModAction {
private static Logger logger = Logger.getLogger(BookConversionAction.class.getName());
private final short actionId;
private final ActionEntry actionEntry;
public BookConversionAction() {
actionId = (short) ModActions.getNextActionId();
actionEntry = ActionEntry.createEntry(
actionId,
"Convert faith",
"converting",
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)
{
return this.getBehavioursFor(performer, object);
}
// Menu without activated object
@Override
public List<ActionEntry> getBehavioursFor(Creature performer, Item object)
{
if(performer instanceof Player && object != null && object.getTemplateId() == BookOfConversion.templateId) {
return Collections.singletonList(actionEntry);
}
return null;
}
};
}
@Override
public ActionPerformer getActionPerformer()
{
return new ActionPerformer() {
@Override
public short getActionId() {
return actionId;
}
// Without activated object
@Override
public boolean action(Action act, Creature performer, Item target, short action, float counter)
{
if(performer instanceof Player){
Player player = (Player) performer;
BookConversionQuestion bcq = new BookConversionQuestion(performer, "Faith Conversion", "Which faith would you like to conver to?", performer.getWurmId(), target);
bcq.sendQuestion();
}else{
logger.info("Somehow a non-player activated a "+target.getName()+"...");
}
return true;
}
@Override
public boolean action(Action act, Creature performer, Item source, Item target, short action, float counter)
{
return this.action(act, performer, target, action, counter);
}
}; // ActionPerformer
}
}

View File

@@ -96,7 +96,7 @@ public class ChaosCrystalInfuseAction implements ModAction {
performer.sendActionControl("Infusing", true, act.getTimeLeft());
}else if(counter * 10f > performer.getCurrentAction().getTimeLeft()){
double diff = Crystals.getInfusionDifficulty(performer, source, target);
double power = performer.getSkills().getSkill(SkillList.ARCHAEOLOGY).skillCheck(diff, source, 0d, false, 1);
double power = performer.getSkills().getSkill(SkillList.SOUL_DEPTH).skillCheck(diff, source, 0d, false, 1);
if(power > 90){
performer.getCommunicator().sendNormalServerMessage("You handle the crystals expertly and infuse the "+target.getName()+ ", increasing its rarity!");
target.setRarity(source.getRarity());

View File

@@ -83,18 +83,18 @@ public class CrystalCombineAction implements ModAction {
if(counter == 1.0f){
performer.getCommunicator().sendNormalServerMessage("You begin to combine the crystals together.");
Server.getInstance().broadCastAction(performer.getName() + " begins combining crystals.", performer, 5);
Skill artifacts = performer.getSkills().getSkill(SkillList.ARCHAEOLOGY);
Skill artifacts = performer.getSkills().getSkill(SkillList.MIND_LOGICAL);
int time = Actions.getSlowActionTime(performer, artifacts, source, 0d);
act.setTimeLeft(time);
performer.sendActionControl("Combining", true, act.getTimeLeft());
}else if(counter * 10f > performer.getCurrentAction().getTimeLeft()){
double diff = (source.getCurrentQualityLevel()+target.getCurrentQualityLevel())*0.5d;
diff += source.getRarity()*(Servers.localServer.PVPSERVER ? 25 : 15);
double diff = (source.getCurrentQualityLevel()+target.getCurrentQualityLevel())*0.4d;
diff += source.getRarity()*15;
diff -= performer.getSoulDepth().getKnowledge();
if(Servers.localServer.PVPSERVER){ // Added difficulty to account for PvP epic curve:
diff *= 1.4f;
}
double power = performer.getSkills().getSkill(SkillList.ARCHAEOLOGY).skillCheck(diff, source, 0d, false, 1);
double power = performer.getSkills().getSkill(SkillList.MIND_LOGICAL).skillCheck(diff, source, 0d, false, 1);
if(power > 0){
performer.getCommunicator().sendNormalServerMessage("You successfully combine the crystals!");
Server.getInstance().broadCastAction(performer.getName() + " successfully combines the crystals!", performer, 5);

View File

@@ -1,10 +1,6 @@
package mod.sin.actions.items;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -55,7 +51,7 @@ public class DepthDrillAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item object, int tilex, int tiley, boolean onSurface, boolean corner, int tile)
{
if(performer instanceof Player && object != null && object.getTemplateId() == DepthDrill.templateId){
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;
}

View File

@@ -5,6 +5,10 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.wurmonline.server.Servers;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.VillageRole;
import com.wurmonline.server.villages.Villages;
import org.gotti.wurmunlimited.modsupport.actions.ActionPerformer;
import org.gotti.wurmunlimited.modsupport.actions.BehaviourProvider;
import org.gotti.wurmunlimited.modsupport.actions.ModAction;
@@ -84,6 +88,20 @@ public class DisintegrationRodAction implements ModAction {
performer.getCommunicator().sendSafeServerMessage("You must use a Disintegration Rod to do this.");
return true;
}
Village v = Villages.getVillage(tilex, tiley, true);
if (v != null) {
boolean ok = false;
VillageRole r = v.getRoleFor(performer);
if (r == null || !r.mayMineRock() || !r.mayReinforce()) {
if (Servers.localServer.PVPSERVER && System.currentTimeMillis() - v.plan.getLastDrained() > 7200000) {
performer.getCommunicator().sendNormalServerMessage("The settlement has not been drained during the last two hours and the wall still stands this time.", (byte) 3);
return true;
}else if(!Servers.localServer.PVPSERVER) {
performer.getCommunicator().sendNormalServerMessage("You do not have permission to use that here.");
return true;
}
}
}
byte type = Tiles.decodeType(newTile);
if (Tiles.isSolidCave(type)) {
int resource = Server.getCaveResource(tilex, tiley);

View File

@@ -1,6 +1,7 @@
package mod.sin.actions.items;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -56,7 +57,7 @@ public class EnchantersCrystalInfuseAction implements ModAction {
public List<ActionEntry> getBehavioursFor(Creature performer, Item source, Item object)
{
if(performer instanceof Player && source != null && object != null && source.getTemplateId() == EnchantersCrystal.templateId && object.getTemplateId() != EnchantersCrystal.templateId){
return Arrays.asList(actionEntry);
return Collections.singletonList(actionEntry);
}
return null;
}
@@ -96,7 +97,7 @@ public class EnchantersCrystalInfuseAction implements ModAction {
double power = -100;
int i = source.getRarity();
while(i >= 0){
power = Math.max(power, performer.getSkills().getSkill(SkillList.ARCHAEOLOGY).skillCheck(diff, source, 0d, false, 1));
power = Math.max(power, performer.getSkills().getSkill(SkillList.SOUL_DEPTH).skillCheck(diff, source, 0d, false, 1));
i--;
}
ItemSpellEffects effs = target.getSpellEffects();

View File

@@ -22,7 +22,7 @@ import com.wurmonline.server.players.Player;
import mod.sin.items.ArenaCache;
import mod.sin.items.ArenaSupplyDepot;
import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.arena.SupplyDepots;
import mod.sin.wyvern.SupplyDepots;
public class SupplyDepotAction implements ModAction {
private static Logger logger = Logger.getLogger(SupplyDepotAction.class.getName());
@@ -112,9 +112,10 @@ public class SupplyDepotAction implements ModAction {
inv.insertItem(cache, true);
performer.getCommunicator().sendSafeServerMessage("You have successfully captured the depot!");
Server.getInstance().broadCastAction(performer.getName() + " successfully captures the depot!", performer, 50);
MiscChanges.sendImportantMessage(performer, performer.getName()+" has claimed an Arena depot!", 255, 128, 0);
SupplyDepots.broadcastCapture(performer);
SupplyDepots.removeSupplyDepot(target);
Items.destroyItem(target.getWurmId());
SupplyDepots.addPlayerStatsDepot(performer.getName());
return true;
}
}else{

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -26,7 +27,21 @@ public class Avenger implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -35,7 +50,7 @@ public class Avenger implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.avenger", "Avenger", "Sent from the heavens to purge the unworthy.",
"model.creature.humanoid.avenger.light", types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"model.creature.humanoid.avenger.light", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.giant", "sound.death.giant", "sound.combat.hit.giant", "sound.combat.hit.giant",
0.3f, 25f, 0f, 0f, 0.0f, 0.0f, 1.2f, 500,
new int[]{}, 15, 70, Materials.MATERIAL_MEAT_HUMANOID);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -46,24 +47,24 @@ public class Charger implements ModCreature, CreatureTypes {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.charger", "Charger", "A blazing-fast stallion.",
"model.creature.quadraped.horse.hell", types, BodyTemplate.TYPE_HORSE, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.horse", "sound.death.horse", "sound.combat.hit.horse", "sound.combat.hit.horse",
1.1f, 12f, 10f, 10.0f, 0.0f, 0.0f, 1.6f, 1000,
1.1f, 9f, 7f, 7f, 0.0f, 0.0f, 1.6f, 1000,
new int[]{}, 10, 74, Materials.MATERIAL_MEAT_HORSE);
builder.skill(SkillList.BODY_STRENGTH, 37.0f);
builder.skill(SkillList.BODY_STRENGTH, 32.0f);
builder.skill(SkillList.BODY_STAMINA, 30.0f);
builder.skill(SkillList.BODY_CONTROL, 25.0f);
builder.skill(SkillList.MIND_LOGICAL, 30.0f);
builder.skill(SkillList.MIND_SPEED, 20.0f);
builder.skill(SkillList.SOUL_STRENGTH, 30.0f);
builder.skill(SkillList.SOUL_DEPTH, 30.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 25.0f);
builder.skill(SkillList.GROUP_FIGHTING, 20.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 20.0f);
builder.skill(SkillList.GROUP_FIGHTING, 16.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("burn");
builder.maxAge(100);
builder.armourType(ArmourTypes.ARMOUR_LEATHER);
builder.baseCombatRating(13.0f);
builder.baseCombatRating(6.5f);
builder.combatDamageType(Wound.TYPE_BURN);
builder.denMaterial(Materials.MATERIAL_WOOD_BIRCH);
builder.denName("charger lair");
@@ -87,13 +88,13 @@ public class Charger implements ModCreature, CreatureTypes {
vehicle.createPassengerSeats(0);
vehicle.setSeatFightMod(0, 0.8f, 1.1f);
vehicle.setSeatOffset(0, 0.0f, 0.0f, 0.3f);
vehicle.setSeatOffset(0, 0.0f, 0.0f, 0.0f);
vehicle.setCreature(true);
vehicle.setSkillNeeded(37.0f);
vehicle.setSkillNeeded(Servers.localServer.PVPSERVER ? 25.0f : 37.0f);
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(0.09f);
vehicle.setMaxHeightDiff(0.06f);
vehicle.setMaxDepth(-1.7f);
vehicle.setMaxSpeed(46.0f);
vehicle.setMaxSpeed(Servers.localServer.PVPSERVER ? 32.0f : 34.0f);
vehicle.setCommandType((byte) 3);
vehicle.setCanHaveEquipment(true);
}
@@ -105,6 +106,7 @@ public class Charger implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_STEPPE.id)
.addCreatures(templateId, 1)
.build(3);
@@ -113,4 +115,5 @@ public class Charger implements ModCreature, CreatureTypes {
.addCreatures(templateId, 1)
.build(1);
}
}
}

View File

@@ -0,0 +1,67 @@
package mod.sin.creatures;
import com.wurmonline.server.bodys.BodyTemplate;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.combat.ArmourTypes;
import com.wurmonline.server.creatures.CreatureTypes;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.skills.SkillList;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
public class FireCrab implements ModCreature, CreatureTypes {
public static int templateId;
@Override
public CreatureTemplateBuilder createCreateTemplateBuilder() {
// {C_TYPE_MOVE_LOCAL, C_TYPE_VEHICLE, C_TYPE_ANIMAL, C_TYPE_LEADABLE, C_TYPE_GRAZER, C_TYPE_OMNIVORE, C_TYPE_DOMINATABLE, C_TYPE_AGG_HUMAN, C_TYPE_NON_NEWBIE, C_TYPE_BURNING}; - Hell Horse
// int[] types = new int[]{7, 6, 13, 3, 29, 39, 60, 61}; - Spider
int[] types = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_NON_NEWBIE
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
// final String modelName, final int[] types, final byte bodyType, final short vision, final byte sex, final short centimetersHigh, final short centimetersLong, final short centimetersWide,
// final String deathSndMale, final String deathSndFemale, final String hitSndMale, final String hitSndFemale,
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.fire.crab", "Fire crab", "A crab lit on fire. I wonder how...",
"model.creature.quadraped.crab", types, BodyTemplate.TYPE_DOG, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.combat.crab.death", "sound.combat.crab.death", "sound.combat.crab.attack", "sound.combat.crab.attack2",
0.6f, 9f, 0f, 12.0f, 0.0f, 0.0f, 1.0f, 500,
new int[]{}, 10, 74, Materials.MATERIAL_MEAT_SEAFOOD);
builder.skill(SkillList.BODY_STRENGTH, 20.0f);
builder.skill(SkillList.BODY_STAMINA, 30.0f);
builder.skill(SkillList.BODY_CONTROL, 35.0f);
builder.skill(SkillList.MIND_LOGICAL, 30.0f);
builder.skill(SkillList.MIND_SPEED, 30.0f);
builder.skill(SkillList.SOUL_STRENGTH, 30.0f);
builder.skill(SkillList.SOUL_DEPTH, 30.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 35.0f);
builder.skill(SkillList.GROUP_FIGHTING, 25.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("claw");
builder.maxAge(100);
builder.armourType(ArmourTypes.ARMOUR_CLOTH);
builder.baseCombatRating(7.0f);
builder.combatDamageType(Wound.TYPE_BURN);
builder.maxGroupAttackSize(100);
templateId = builder.getTemplateId();
return builder;
}
@Override
public void addEncounters() {
if (templateId == 0)
return;
}
}

View File

@@ -0,0 +1,84 @@
package mod.sin.creatures;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.Servers;
import com.wurmonline.server.bodys.BodyTemplate;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.combat.ArmourTypes;
import com.wurmonline.server.creatures.CreatureTypes;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.skills.SkillList;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
public class FireGiant implements ModCreature, CreatureTypes {
public static int templateId;
@Override
public CreatureTemplateBuilder createCreateTemplateBuilder() {
// {C_TYPE_MOVE_LOCAL, C_TYPE_VEHICLE, C_TYPE_ANIMAL, C_TYPE_LEADABLE, C_TYPE_GRAZER, C_TYPE_OMNIVORE, C_TYPE_DOMINATABLE, C_TYPE_AGG_HUMAN, C_TYPE_NON_NEWBIE, C_TYPE_BURNING}; - Hell Horse
// int[] types = new int[]{7, 6, 13, 3, 29, 39, 60, 61}; - Spider
int[] types = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
// final String modelName, final int[] types, final byte bodyType, final short vision, final byte sex, final short centimetersHigh, final short centimetersLong, final short centimetersWide,
// final String deathSndMale, final String deathSndFemale, final String hitSndMale, final String hitSndFemale,
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.fire.giant", "Fire giant", "A lumbering, burning hulk.",
"model.creature.humanoid.giant.forest", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_ETTIN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.giant", "sound.death.giant", "sound.combat.hit.giant", "sound.combat.hit.giant",
0.3f, 22f, 18f, 0f, 0.0f, 0.0f, 0.7f, 300,
new int[]{ItemList.heart, ItemList.eye, ItemList.gland, ItemList.tooth}, 15, 70, Materials.MATERIAL_MEAT_TOUGH);
builder.skill(SkillList.BODY_STRENGTH, 55.0f);
builder.skill(SkillList.BODY_STAMINA, 65.0f);
builder.skill(SkillList.BODY_CONTROL, 30.0f);
builder.skill(SkillList.MIND_LOGICAL, 10.0f);
builder.skill(SkillList.MIND_SPEED, 10.0f);
builder.skill(SkillList.SOUL_STRENGTH, 10.0f);
builder.skill(SkillList.SOUL_DEPTH, 10.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 70.0f);
builder.skill(SkillList.GROUP_FIGHTING, 50.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("maul");
builder.maxAge(100);
builder.armourType(ArmourTypes.ARMOUR_LEATHER);
builder.baseCombatRating(37.0f);
builder.combatDamageType(Wound.TYPE_BURN);
builder.maxGroupAttackSize(100);
templateId = builder.getTemplateId();
return builder;
}
@Override
public void addEncounters() {
if (templateId == 0)
return;
}
}

View File

@@ -25,7 +25,9 @@ public class ForestSpider implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -34,7 +36,7 @@ public class ForestSpider implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.forest.spider", "Forest spider", "Found amongst trees, these spiders are dangerous and poisonous.",
"model.creature.multiped.spider.huge", types, BodyTemplate.TYPE_SPIDER, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"model.creature.multiped.spider.fog", types, BodyTemplate.TYPE_SPIDER, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.spider", "sound.death.spider", "sound.combat.hit.spider", "sound.combat.hit.spider",
0.6f, 10f, 0f, 13.0f, 0.0f, 0.0f, 1.2f, 500,
new int[]{ItemList.heart}, 10, 74, Materials.MATERIAL_MEAT_INSECT);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -28,7 +29,22 @@ public class Giant implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -37,7 +53,7 @@ public class Giant implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.giant", "Giant", "A lumbering hulk.",
"model.creature.humanoid.giant.forest", types, BodyTemplate.TYPE_ETTIN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"model.creature.humanoid.giant.forest", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_ETTIN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.giant", "sound.death.giant", "sound.combat.hit.giant", "sound.combat.hit.giant",
0.3f, 19f, 15f, 0f, 0.0f, 0.0f, 0.7f, 300,
new int[]{ItemList.heart, ItemList.eye, ItemList.gland, ItemList.tooth}, 15, 70, Materials.MATERIAL_MEAT_TOUGH);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Server;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -52,7 +53,7 @@ public class HornedPony implements ModCreature, CreatureTypes {
Servers.localServer.PVPSERVER ? 0.75f : 0.4f, 17f, 13f, 15.0f, 0.0f, 0.0f, 1.4f, 800,
new int[]{ItemList.heart}, 10, 74, Materials.MATERIAL_MEAT_HORSE);
builder.skill(SkillList.BODY_STRENGTH, Servers.localServer.PVPSERVER ? 40.0f : 60.0f);
builder.skill(SkillList.BODY_STRENGTH, 40.0f);
builder.skill(SkillList.BODY_STAMINA, 60.0f);
builder.skill(SkillList.BODY_CONTROL, 55.0f);
builder.skill(SkillList.MIND_LOGICAL, 40.0f);
@@ -107,8 +108,10 @@ public class HornedPony implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_ENCHANTED_GRASS.id)
.addCreatures(templateId, 1)
.build(2);
}
}
}

View File

@@ -0,0 +1,69 @@
package mod.sin.creatures;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.bodys.BodyTemplate;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.combat.ArmourTypes;
import com.wurmonline.server.creatures.CreatureTypes;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.skills.SkillList;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
public class IceCat implements ModCreature, CreatureTypes {
public static int templateId;
@Override
public CreatureTemplateBuilder createCreateTemplateBuilder() {
// {C_TYPE_MOVE_LOCAL, C_TYPE_VEHICLE, C_TYPE_ANIMAL, C_TYPE_LEADABLE, C_TYPE_GRAZER, C_TYPE_OMNIVORE, C_TYPE_DOMINATABLE, C_TYPE_AGG_HUMAN, C_TYPE_NON_NEWBIE, C_TYPE_BURNING}; - Hell Horse
// int[] types = new int[]{7, 6, 13, 3, 29, 39, 60, 61}; - Spider
int[] types = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_NON_NEWBIE
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
// final String modelName, final int[] types, final byte bodyType, final short vision, final byte sex, final short centimetersHigh, final short centimetersLong, final short centimetersWide,
// final String deathSndMale, final String deathSndFemale, final String hitSndMale, final String hitSndFemale,
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.ice.cat", "Iced wild cat", "A bone-chilling feline.",
"model.creature.quadraped.cat.wild", types, BodyTemplate.TYPE_DOG, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.cat", "sound.death.cat", "sound.combat.hit.cat", "sound.combat.hit.cat",
0.6f, 7f, 0f, 10.0f, 0.0f, 0.0f, 1.0f, 500,
new int[]{}, 10, 74, Materials.MATERIAL_MEAT_CAT);
builder.skill(SkillList.BODY_STRENGTH, 20.0f);
builder.skill(SkillList.BODY_STAMINA, 30.0f);
builder.skill(SkillList.BODY_CONTROL, 35.0f);
builder.skill(SkillList.MIND_LOGICAL, 30.0f);
builder.skill(SkillList.MIND_SPEED, 30.0f);
builder.skill(SkillList.SOUL_STRENGTH, 30.0f);
builder.skill(SkillList.SOUL_DEPTH, 30.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 30.0f);
builder.skill(SkillList.GROUP_FIGHTING, 20.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("claw");
builder.maxAge(100);
builder.armourType(ArmourTypes.ARMOUR_CLOTH);
builder.baseCombatRating(5.0f);
builder.combatDamageType(Wound.TYPE_COLD);
builder.maxGroupAttackSize(100);
templateId = builder.getTemplateId();
return builder;
}
@Override
public void addEncounters() {
if (templateId == 0)
return;
}
}

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -25,7 +26,9 @@ public class LargeBoar implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -71,10 +74,10 @@ public class LargeBoar implements ModCreature, CreatureTypes {
new EncounterBuilder(Tiles.Tile.TILE_SAND.id)
.addCreatures(templateId, 1)
.build(2);
.build(Servers.localServer.PVPSERVER ? 1 : 2);
new EncounterBuilder(Tiles.Tile.TILE_GRASS.id)
.addCreatures(templateId, 1)
.build(3);
.build(Servers.localServer.PVPSERVER ? 1 : 3);
}
}

View File

@@ -22,17 +22,18 @@ public class Reaper implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_HERBIVORE,
CreatureTypes.C_TYPE_FENCEBREAKER,
//CreatureTypes.C_TYPE_FENCEBREAKER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_REGENERATING
};
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.reaper", "Reaper",
"The reaper, here to claim the soul of a powerful creature... and anything else.", "model.creature.gmdark",
"The reaper, here to claim the souls of the living.", "model.creature.gmdark",
types, BodyTemplate.TYPE_HUMAN, (short) 20, (byte) 0, (short) 350, (short) 100, (short) 60, "sound.death.dragon",
"sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
0.03f, 35.0f, 45.0f, 22.0f, 40.0f, 0.0f, 2.5f, 500,
new int[]{ItemList.boneCollar}, 40, 100, Materials.MATERIAL_MEAT_HUMANOID);
0.06f, 35.0f, 45.0f, 22.0f, 40.0f, 0.0f, 1.0f, 500,
new int[]{}, 20, 70, Materials.MATERIAL_MEAT_HUMANOID);
builder.skill(SkillList.BODY_STRENGTH, 60.0f);
builder.skill(SkillList.BODY_STAMINA, 70.0f);
@@ -50,7 +51,7 @@ public class Reaper implements ModCreature, CreatureTypes {
builder.maxAge(200);
builder.armourType(ArmourTypes.ARMOUR_SCALE_DRAGON);
builder.baseCombatRating(55.0f);
builder.combatDamageType(Wound.TYPE_INFECTION);
builder.combatDamageType(Wound.TYPE_PIERCE);
builder.maxGroupAttackSize(100);
templateId = builder.getTemplateId();

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -35,9 +36,11 @@ public class SolDemon implements ModCreature {
if (templateId == 0)
return;
if(Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_SAND.id)
.addCreatures(templateId, 2)
.build(1);
}
new EncounterBuilder(Tiles.Tile.TILE_MYCELIUM.id)
.addCreatures(templateId, 2)

View File

@@ -22,17 +22,18 @@ public class SpectralDrake implements ModCreature {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_HERBIVORE,
CreatureTypes.C_TYPE_FENCEBREAKER,
//CreatureTypes.C_TYPE_FENCEBREAKER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_REGENERATING
};
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.spectraldrake", "Spectral drake",
"The spectral incarnation of a defeated dragon.", "model.creature.drake.spirit", types, BodyTemplate.TYPE_DRAGON,
(short) 20, (byte) 0, (short) 350, (short) 100, (short) 60, "sound.death.dragon", "sound.death.dragon",
"sound.combat.hit.dragon", "sound.combat.hit.dragon",
0.06f, 45.0f, 50.0f, 22.0f, 45.0f, 0.0f, 2.0f, 500,
new int[]{ItemList.boneCollar}, 40, 100, Materials.MATERIAL_MEAT_DRAGON);
0.08f, 45.0f, 50.0f, 27.0f, 45.0f, 0.0f, 1.0f, 500,
new int[]{}, 20, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, 60.0f);
builder.skill(SkillList.BODY_STAMINA, 70.0f);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -29,7 +30,25 @@ public class SpiritTroll implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_CLIMBER,
CreatureTypes.C_TYPE_UNDEAD,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_FENCEBREAKER,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_CLIMBER,
CreatureTypes.C_TYPE_UNDEAD,
CreatureTypes.C_TYPE_DETECTINVIS,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -38,7 +57,7 @@ public class SpiritTroll implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.spirit.troll", "Spirit troll", "A spirit troll.",
"model.creature.humanoid.troll.standard", types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"model.creature.humanoid.troll.standard", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 0, (short) 85, (short) 50, (short) 85,
"sound.death.troll", "sound.death.troll", "sound.combat.hit.troll", "sound.combat.hit.troll",
0.15f, 15f, 17f, 19.0f, 0.0f, 0.0f, 1.2f, 500,
new int[]{}, 10, 74, (byte) 82);

View File

@@ -0,0 +1,105 @@
package mod.sin.creatures;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.Servers;
import com.wurmonline.server.behaviours.Vehicle;
import com.wurmonline.server.bodys.BodyTemplate;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.combat.ArmourTypes;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.CreatureTypes;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.skills.SkillList;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
import org.gotti.wurmunlimited.modsupport.vehicles.ModVehicleBehaviour;
import org.gotti.wurmunlimited.modsupport.vehicles.VehicleFacade;
public class Terror implements ModCreature, CreatureTypes {
public static int templateId;
@Override
public CreatureTemplateBuilder createCreateTemplateBuilder() {
// {C_TYPE_MOVE_LOCAL, C_TYPE_VEHICLE, C_TYPE_ANIMAL, C_TYPE_LEADABLE, C_TYPE_GRAZER, C_TYPE_OMNIVORE, C_TYPE_DOMINATABLE, C_TYPE_AGG_HUMAN, C_TYPE_NON_NEWBIE, C_TYPE_BURNING}; - Hell Horse
int[] types = {
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_HERBIVORE,
//CreatureTypes.C_TYPE_FENCEBREAKER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_REGENERATING
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
// final String modelName, final int[] types, final byte bodyType, final short vision, final byte sex, final short centimetersHigh, final short centimetersLong, final short centimetersWide,
// final String deathSndMale, final String deathSndFemale, final String hitSndMale, final String hitSndFemale,
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.terror", "Terror", "Run.",
"model.creature.dragon.red", types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
1.0f, 3.0f, 3.0f, 0.0f, 0.0f, 0.0f, 2.5f, 2500,
new int[]{}, 7, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, 22.0f);
builder.skill(SkillList.BODY_STAMINA, 20.0f);
builder.skill(SkillList.BODY_CONTROL, 20.0f);
builder.skill(SkillList.MIND_LOGICAL, 20.0f);
builder.skill(SkillList.MIND_SPEED, 20.0f);
builder.skill(SkillList.SOUL_STRENGTH, 20.0f);
builder.skill(SkillList.SOUL_DEPTH, 20.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 25.0f);
builder.skill(SkillList.GROUP_FIGHTING, 25.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("bite");
builder.kickDamString("wingbuff");
builder.maxAge(200);
builder.armourType(ArmourTypes.ARMOUR_SCALE_DRAGON);
builder.baseCombatRating(3.0f);
builder.combatDamageType(Wound.TYPE_BURN);
builder.maxGroupAttackSize(10);
templateId = builder.getTemplateId();
return builder;
}
public ModVehicleBehaviour getVehicleBehaviour() {
return new ModVehicleBehaviour() {
@Override
public void setSettingsForVehicle(Item item, Vehicle vehicle) {
}
@Override
public void setSettingsForVehicle(Creature creature, Vehicle v) {
VehicleFacade vehicle = wrap(v);
vehicle.createPassengerSeats(0);
vehicle.setSeatFightMod(0, 0.8f, 1.1f);
vehicle.setSeatOffset(0, 0.2f, 0.0f, 0.0f);
vehicle.setCreature(true);
vehicle.setSkillNeeded(95f);
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(0.10f);
vehicle.setMaxDepth(-50f);
vehicle.setMaxSpeed(90.0f);
vehicle.setCommandType((byte) 3);
vehicle.setCanHaveEquipment(true);
}
};
}
@Override
public void addEncounters() {
if (templateId == 0)
return;
}
}

View File

@@ -35,7 +35,24 @@ public class WyvernBlack implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_MOVE_GLOBAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -44,12 +61,12 @@ public class WyvernBlack implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.wyvern.black", "Black wyvern", "A battle-hardened wyvern with scales as black as night.",
"model.creature.drake.black", types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"model.creature.drake.black", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
Servers.localServer.PVPSERVER ? 0.65f : 0.35f, 20.0f, 23.0f, 0.0f, 0.0f, 0.0f, 1.3f, 800,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 40, 70, Materials.MATERIAL_MEAT_DRAGON);
Servers.localServer.PVPSERVER ? 0.65f : 0.35f, 20.0f, 23.0f, 0.0f, 0.0f, 0.0f, 1.0f, 700,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 10, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, Servers.localServer.PVPSERVER ? 39f : 54f);
builder.skill(SkillList.BODY_STRENGTH, 39f);
builder.skill(SkillList.BODY_STAMINA, 50.0f);
builder.skill(SkillList.BODY_CONTROL, 50.0f);
builder.skill(SkillList.MIND_LOGICAL, 50.0f);
@@ -93,7 +110,7 @@ public class WyvernBlack implements ModCreature, CreatureTypes {
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(0.15f);
vehicle.setMaxDepth(-50f);
vehicle.setMaxSpeed(51.0f);
vehicle.setMaxSpeed(35.0f);
vehicle.setCommandType((byte) 3);
}
};
@@ -104,18 +121,18 @@ public class WyvernBlack implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_SAND.id)
.addCreatures(templateId, 1)
.build(1);
if(Servers.localServer.PVPSERVER){
new EncounterBuilder(Tiles.Tile.TILE_GRASS.id)
//}else if(Servers.localServer.PVPSERVER){
/*new EncounterBuilder(Tiles.Tile.TILE_GRASS.id)
.addCreatures(templateId, 1)
.build(1);
new EncounterBuilder(Tiles.Tile.TILE_TREE.id)
.addCreatures(templateId, 1)
.build(1);
.build(1);*/
}
}
}

View File

@@ -0,0 +1,123 @@
package mod.sin.creatures;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.Servers;
import com.wurmonline.server.behaviours.Vehicle;
import com.wurmonline.server.bodys.BodyTemplate;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.combat.ArmourTypes;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.CreatureTypes;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.skills.SkillList;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.EncounterBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
import org.gotti.wurmunlimited.modsupport.vehicles.ModVehicleBehaviour;
import org.gotti.wurmunlimited.modsupport.vehicles.VehicleFacade;
public class WyvernBlue implements ModCreature, CreatureTypes {
public static int templateId;
@Override
public CreatureTemplateBuilder createCreateTemplateBuilder() {
// {C_TYPE_MOVE_LOCAL, C_TYPE_VEHICLE, C_TYPE_ANIMAL, C_TYPE_LEADABLE, C_TYPE_GRAZER, C_TYPE_OMNIVORE, C_TYPE_DOMINATABLE, C_TYPE_AGG_HUMAN, C_TYPE_NON_NEWBIE, C_TYPE_BURNING}; - Hell Horse
int[] types = {
CreatureTypes.C_TYPE_HERBIVORE,
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_GRAZER,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_HERBIVORE,
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_GRAZER,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
// final String modelName, final int[] types, final byte bodyType, final short vision, final byte sex, final short centimetersHigh, final short centimetersLong, final short centimetersWide,
// final String deathSndMale, final String deathSndFemale, final String hitSndMale, final String hitSndFemale,
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.wyvern.blue", "Blue wyvern", "A battle-hardened wyvern with scales reflecting the colors of the sea.",
"model.creature.drake.blue", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
Servers.localServer.PVPSERVER ? 0.5f : 0.25f, 20.0f, 23.0f, 0.0f, 0.0f, 0.0f, 1.4f, 1200,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 10, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, 41.0f);
builder.skill(SkillList.BODY_STAMINA, 50.0f);
builder.skill(SkillList.BODY_CONTROL, 65.0f);
builder.skill(SkillList.MIND_LOGICAL, 50.0f);
builder.skill(SkillList.MIND_SPEED, 50.0f);
builder.skill(SkillList.SOUL_STRENGTH, 50.0f);
builder.skill(SkillList.SOUL_DEPTH, 50.0f);
builder.skill(SkillList.WEAPONLESS_FIGHTING, 50.0f);
builder.skill(SkillList.GROUP_FIGHTING, 50.0f);
builder.boundsValues(-0.5f, -1.0f, 0.5f, 1.42f);
builder.handDamString("bite");
builder.kickDamString("wingbuff");
builder.maxAge(200);
builder.armourType(Servers.localServer.PVPSERVER ? ArmourTypes.ARMOUR_CLOTH : ArmourTypes.ARMOUR_SCALE_DRAGON);
builder.baseCombatRating(24.0f);
builder.combatDamageType(Wound.TYPE_WATER);
builder.maxGroupAttackSize(10);
templateId = builder.getTemplateId();
return builder;
}
public ModVehicleBehaviour getVehicleBehaviour() {
return new ModVehicleBehaviour() {
@Override
public void setSettingsForVehicle(Item item, Vehicle vehicle) {
}
@Override
public void setSettingsForVehicle(Creature creature, Vehicle v) {
VehicleFacade vehicle = wrap(v);
vehicle.createPassengerSeats(0);
vehicle.setSeatFightMod(0, 0.9f, 1.2f);
vehicle.setSeatOffset(0, 0.2f, 0.0f, 0.0f);
vehicle.setCanHaveEquipment(true);
vehicle.setCreature(true);
vehicle.setSkillNeeded(Servers.localServer.PVPSERVER ? 45f : 50f);
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(0.18f);
vehicle.setMaxDepth(-10f);
vehicle.setMaxSpeed(38.0f);
vehicle.setCommandType((byte) 3);
}
};
}
@Override
public void addEncounters() {
if (templateId == 0)
return;
}
}

View File

@@ -34,7 +34,23 @@ public class WyvernGreen implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_GRAZER
CreatureTypes.C_TYPE_GRAZER,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_HERBIVORE,
CreatureTypes.C_TYPE_MOVE_LOCAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_GRAZER,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -43,12 +59,12 @@ public class WyvernGreen implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.wyvern.green", "Green wyvern", "A battle-hardened wyvern with scales as green as the leaves.",
"model.creature.drake.green", types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"model.creature.drake.green", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
Servers.localServer.PVPSERVER ? 0.7f : 0.4f, 20.0f, 23.0f, 0.0f, 0.0f, 0.0f, 1.7f, 1500,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 40, 70, Materials.MATERIAL_MEAT_DRAGON);
Servers.localServer.PVPSERVER ? 0.7f : 0.4f, 20.0f, 23.0f, 0.0f, 0.0f, 0.0f, 1.4f, 1200,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 10, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, Servers.localServer.PVPSERVER ? 40f : 55f);
builder.skill(SkillList.BODY_STRENGTH, 39.0f);
builder.skill(SkillList.BODY_STAMINA, 50.0f);
builder.skill(SkillList.BODY_CONTROL, 50.0f);
builder.skill(SkillList.MIND_LOGICAL, 50.0f);
@@ -92,7 +108,7 @@ public class WyvernGreen implements ModCreature, CreatureTypes {
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(0.18f);
vehicle.setMaxDepth(-10f);
vehicle.setMaxSpeed(52.0f);
vehicle.setMaxSpeed(35.0f);
vehicle.setCommandType((byte) 3);
}
};
@@ -103,6 +119,7 @@ public class WyvernGreen implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_GRASS.id)
.addCreatures(templateId, 1)
.build(1);
@@ -111,4 +128,5 @@ public class WyvernGreen implements ModCreature, CreatureTypes {
.addCreatures(templateId, 1)
.build(1);
}
}
}

View File

@@ -34,7 +34,23 @@ public class WyvernRed implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_MOVE_GLOBAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -43,12 +59,12 @@ public class WyvernRed implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.wyvern.red", "Red wyvern", "A battle-hardened wyvern with scales as red as fire.",
"model.creature.drake.red", types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"model.creature.drake.red", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
Servers.localServer.PVPSERVER ? 0.6f : 0.17f, 22.0f, 25.0f, 0.0f, 0.0f, 0.0f, 1.4f, 900,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 40, 70, Materials.MATERIAL_MEAT_DRAGON);
Servers.localServer.PVPSERVER ? 0.6f : 0.2f, 22.0f, 25.0f, 0.0f, 0.0f, 0.0f, 1.2f, 800,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 7, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, Servers.localServer.PVPSERVER ? 37f : 52f);
builder.skill(SkillList.BODY_STRENGTH, 39.0f);
builder.skill(SkillList.BODY_STAMINA, 50.0f);
builder.skill(SkillList.BODY_CONTROL, 50.0f);
builder.skill(SkillList.MIND_LOGICAL, 50.0f);
@@ -87,11 +103,11 @@ public class WyvernRed implements ModCreature, CreatureTypes {
vehicle.setSeatFightMod(0, 0.8f, 1.1f);
vehicle.setSeatOffset(0, 0.2f, 0.0f, 0.0f);
vehicle.setCreature(true);
vehicle.setSkillNeeded(Servers.localServer.PVPSERVER ? 35 : 43f);
vehicle.setSkillNeeded(43f);
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(Servers.localServer.PVPSERVER ? 0.15f : 0.10f);
vehicle.setMaxHeightDiff(0.10f);
vehicle.setMaxDepth(-50f);
vehicle.setMaxSpeed(50.0f);
vehicle.setMaxSpeed(35.0f);
vehicle.setCommandType((byte) 3);
vehicle.setCanHaveEquipment(true);
}
@@ -103,8 +119,10 @@ public class WyvernRed implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_ROCK.id)
.addCreatures(templateId, 1)
.build(1);
}
}
}

View File

@@ -35,7 +35,24 @@ public class WyvernWhite implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_DOMINATABLE,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
int[] pvpTypes = {
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_MOVE_GLOBAL,
CreatureTypes.C_TYPE_VEHICLE,
CreatureTypes.C_TYPE_REGENERATING,
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_SWIMMING,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_MONSTER,
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_ANIMAL,
CreatureTypes.C_TYPE_NO_REBIRTH,
CreatureTypes.C_TYPE_MISSION_OK,
CreatureTypes.C_TYPE_MISSION_TRAITOR_OK
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -44,12 +61,12 @@ public class WyvernWhite implements ModCreature, CreatureTypes {
// final float naturalArmour, final float handDam, final float kickDam, final float biteDam, final float headDam, final float breathDam, final float speed, final int moveRate,
// final int[] itemsButchered, final int maxHuntDist, final int aggress) {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.wyvern.white", "White wyvern", "A battle-hardened wyvern with scales as white as the moon.",
"model.creature.drake.white", types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"model.creature.drake.white", Servers.localServer.PVPSERVER ? pvpTypes : types, BodyTemplate.TYPE_DRAGON, (short) 10, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.dragon", "sound.death.dragon", "sound.combat.hit.dragon", "sound.combat.hit.dragon",
Servers.localServer.PVPSERVER ? 0.7f : 0.3f, 17.0f, 20.0f, 0.0f, 0.0f, 0.0f, 1.4f, 900,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 40, 70, Materials.MATERIAL_MEAT_DRAGON);
Servers.localServer.PVPSERVER ? 0.7f : 0.3f, 17.0f, 20.0f, 0.0f, 0.0f, 0.0f, 1.2f, 800,
new int[]{ItemList.animalHide, ItemList.tail, ItemList.eye, ItemList.gland, ItemList.tooth}, 10, 70, Materials.MATERIAL_MEAT_DRAGON);
builder.skill(SkillList.BODY_STRENGTH, Servers.localServer.PVPSERVER ? 43f : 58f);
builder.skill(SkillList.BODY_STRENGTH, 39.0f);
builder.skill(SkillList.BODY_STAMINA, 50.0f);
builder.skill(SkillList.BODY_CONTROL, 50.0f);
builder.skill(SkillList.MIND_LOGICAL, 50.0f);
@@ -88,11 +105,11 @@ public class WyvernWhite implements ModCreature, CreatureTypes {
vehicle.setSeatFightMod(0, 0.8f, 1.1f);
vehicle.setSeatOffset(0, 0.2f, 0.0f, 0.0f);
vehicle.setCreature(true);
vehicle.setSkillNeeded(Servers.localServer.PVPSERVER ? 33f : 40f);
vehicle.setSkillNeeded(40f);
vehicle.setName(creature.getName());
vehicle.setMaxHeightDiff(Servers.localServer.PVPSERVER ? 0.15f : 0.10f);
vehicle.setMaxHeightDiff(0.10f);
vehicle.setMaxDepth(-50f);
vehicle.setMaxSpeed(53.0f);
vehicle.setMaxSpeed(36.0f);
vehicle.setCommandType((byte) 3);
vehicle.setCanHaveEquipment(true);
}
@@ -104,11 +121,11 @@ public class WyvernWhite implements ModCreature, CreatureTypes {
if (templateId == 0)
return;
if(!Servers.localServer.PVPSERVER) {
new EncounterBuilder(Tiles.Tile.TILE_SNOW.id)
.addCreatures(templateId, 1)
.build(1);
if(Servers.localServer.PVPSERVER){
new EncounterBuilder(Tiles.Tile.TILE_TUNDRA.id)
.addCreatures(templateId, 1)
.build(1);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures.titans;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -19,7 +20,8 @@ public class Ifrit implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -30,7 +32,7 @@ public class Ifrit implements ModCreature, CreatureTypes {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.raid.ifrit", "Ifrit", "A valiant warrior of the flame. You feel the presence of Magranon.",
"model.creature.humanoid.giant.juggernaut", types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 0, (short) 350, (short) 100, (short) 60,
"sound.death.magranon.juggernaut", "sound.death.magranon.juggernaut", "sound.combat.hit.magranon.juggernaut", "sound.combat.hit.magranon.juggernaut",
0.014f, 10.0f, 13.0f, 0.0f, 0.0f, 0.0f, 0.5f, 400,
Servers.localServer.PVPSERVER ? 0.028f :0.014f, 10.0f, 13.0f, 0.0f, 0.0f, 0.0f, 0.5f, 400,
new int[]{}, 40, 100, Materials.MATERIAL_MEAT_HUMANOID);
builder.skill(SkillList.BODY_STRENGTH, 99.0f);

View File

@@ -1,5 +1,6 @@
package mod.sin.creatures.titans;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modsupport.CreatureTemplateBuilder;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreature;
@@ -19,7 +20,8 @@ public class Lilith implements ModCreature, CreatureTypes {
CreatureTypes.C_TYPE_AGG_HUMAN,
CreatureTypes.C_TYPE_CARNIVORE,
CreatureTypes.C_TYPE_HUNTING,
CreatureTypes.C_TYPE_NON_NEWBIE
CreatureTypes.C_TYPE_NON_NEWBIE,
CreatureTypes.C_TYPE_NO_REBIRTH
};
//public CreatureTemplateBuilder(final String identifier, final String name, final String description,
@@ -30,7 +32,7 @@ public class Lilith implements ModCreature, CreatureTypes {
CreatureTemplateBuilder builder = new CreatureTemplateBuilder("mod.creature.raid.lilith", "Lilith", "A bold warrior corrupted by darkness. You feel the presence of Libila.",
"model.creature.humanoid.giant.incarnation", types, BodyTemplate.TYPE_HUMAN, (short) 5, (byte) 1, (short) 350, (short) 100, (short) 60,
"sound.death.libila.incarnation", "sound.death.libila.incarnation", "sound.combat.hit.libila.incarnation", "sound.combat.hit.libila.incarnation",
0.015f, 8.0f, 11.0f, 0.0f, 0.0f, 0.0f, 0.5f, 400,
Servers.localServer.PVPSERVER ? 0.03f :0.015f, 8.0f, 11.0f, 0.0f, 0.0f, 0.0f, 0.5f, 400,
new int[]{}, 40, 100, Materials.MATERIAL_MEAT_HUMANOID);
builder.skill(SkillList.BODY_STRENGTH, 99.0f);

View File

@@ -36,7 +36,7 @@ public class AffinityOrb implements ItemTypes, MiscConstants {
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500);
itemBuilder.material(Materials.MATERIAL_CRYSTAL);
itemBuilder.value(3000000);
itemBuilder.value(1000000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();

View File

@@ -39,7 +39,7 @@ public class ArrowPackHunting {
itemBuilder.bodySpaces(MiscConstants.EMPTY_BYTE_PRIMITIVE_ARRAY);
itemBuilder.modelName("model.container.quiver.");
itemBuilder.difficulty(55.0f);
itemBuilder.weightGrams(2500);
itemBuilder.weightGrams(4500);
itemBuilder.material(Materials.MATERIAL_WOOD_BIRCH);
itemBuilder.value(1000);
itemBuilder.isTraded(true);

View File

@@ -39,7 +39,7 @@ public class ArrowPackWar {
itemBuilder.bodySpaces(MiscConstants.EMPTY_BYTE_PRIMITIVE_ARRAY);
itemBuilder.modelName("model.container.quiver.");
itemBuilder.difficulty(55.0f);
itemBuilder.weightGrams(2500);
itemBuilder.weightGrams(4500);
itemBuilder.material(Materials.MATERIAL_WOOD_BIRCH);
itemBuilder.value(1000);
itemBuilder.isTraded(true);

View File

@@ -0,0 +1,44 @@
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 BookOfConversion implements ItemTypes, MiscConstants {
public static Logger logger = Logger.getLogger(BookOfConversion.class.getName());
public static int templateId;
public void createTemplate() throws IOException{
String name = "book of conversion";
ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.item.book.conversion");
itemBuilder.name(name, "books of conversion", "A book used to convert religion. This comes at a slight faith loss.");
itemBuilder.itemTypes(new short[]{
ItemTypes.ITEM_TYPE_MAGIC,
ItemTypes.ITEM_TYPE_FULLPRICE,
ItemTypes.ITEM_TYPE_NOSELLBACK,
ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE
});
itemBuilder.imageNumber((short) 328);
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.tomemagic.black.paper.");
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500);
itemBuilder.material(Materials.MATERIAL_PAPER);
itemBuilder.value(50000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();
templateId = template.getTemplateId();
logger.info(name+" TemplateID: "+templateId);
}
}

View File

@@ -33,7 +33,7 @@ public class DisintegrationRod implements ItemTypes, MiscConstants {
itemBuilder.difficulty(300.0f);
itemBuilder.weightGrams(1000);
itemBuilder.material(Materials.MATERIAL_STONE);
itemBuilder.value(50000);
itemBuilder.value(20000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();

View File

@@ -40,7 +40,7 @@ public class EternalReservoir implements ItemTypes, MiscConstants {
itemBuilder.primarySkill((int)MiscConstants.NOID);
itemBuilder.bodySpaces(EMPTY_BYTE_PRIMITIVE_ARRAY);
itemBuilder.modelName("model.structure.rift.altar.1.");
itemBuilder.difficulty(50.0f);
itemBuilder.difficulty(40.0f);
itemBuilder.weightGrams(200000);
itemBuilder.material(Materials.MATERIAL_STONE);
itemBuilder.value(10000);
@@ -59,14 +59,8 @@ public class EternalReservoir implements ItemTypes, MiscConstants {
massStorage.addRequirement(new CreationRequirement(1, ItemList.dirtPile, 99, true));
massStorage.addRequirement(new CreationRequirement(2, ItemList.brickPottery, 200, true));
massStorage.addRequirement(new CreationRequirement(3, ItemList.peat, 50, true));
massStorage.addRequirement(new CreationRequirement(4, ChaosCrystal.templateId, 50, true));
massStorage.addRequirement(new CreationRequirement(5, ItemList.heart, 20, true));
massStorage.addRequirement(new CreationRequirement(6, ItemList.emerald, 5, true));
massStorage.addRequirement(new CreationRequirement(7, ItemList.diamond, 5, true));
massStorage.addRequirement(new CreationRequirement(8, ItemList.opal, 5, true));
massStorage.addRequirement(new CreationRequirement(9, ItemList.sapphire, 5, true));
massStorage.addRequirement(new CreationRequirement(10, ItemList.ruby, 5, true));
massStorage.addRequirement(new CreationRequirement(3, ChaosCrystal.templateId, 30, true));
massStorage.addRequirement(new CreationRequirement(4, ItemList.heart, 20, true));
}
}
}

View File

@@ -0,0 +1,51 @@
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 KeyFragment implements ItemTypes, MiscConstants {
public static Logger logger = Logger.getLogger(KeyFragment.class.getName());
public static int templateId;
public void createTemplate() throws IOException{
/* ItemTemplateCreatorContinued.createItemTemplate(737, "Valrei mission item", "items", "excellent", "good", "ok", "poor",
* "A weird item belonging on Valrei.",
* new short[]{32, 59, 147, 60},
* 462, 1, 0, 86400, 3, 5, 50, -10, MiscConstants.EMPTY_BYTE_PRIMITIVE_ARRAY,
* "model.valrei.", 300.0f, 100, 21, 1, false);
*/
String name = "key fragment [1/50]";
ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.fragment.key");
itemBuilder.name(name, "key fragments", "A fragment of the fabled Key of the Heavens.");
itemBuilder.itemTypes(new short[]{
ItemTypes.ITEM_TYPE_MAGIC,
ItemTypes.ITEM_TYPE_FULLPRICE,
ItemTypes.ITEM_TYPE_NOSELLBACK,
ItemTypes.ITEM_TYPE_SERVERBOUND,
ItemTypes.ITEM_TYPE_ARTIFACT
});
itemBuilder.imageNumber((short) 462);
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.decoration.gem.resurrectionstone."); //model.valrei.magic
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(250);
itemBuilder.material(Materials.MATERIAL_CRYSTAL);
itemBuilder.value(5000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();
templateId = template.getTemplateId();
logger.info(name+" TemplateID: "+templateId);
}
}

View File

@@ -35,7 +35,7 @@ public class SealedMap implements ItemTypes, MiscConstants {
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500);
itemBuilder.material(Materials.MATERIAL_MAGIC);
itemBuilder.value(5000000);
itemBuilder.value(2000000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();

View File

@@ -0,0 +1,51 @@
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 SorceryFragment implements ItemTypes, MiscConstants {
public static Logger logger = Logger.getLogger(SorceryFragment.class.getName());
public static int templateId;
public void createTemplate() throws IOException{
/* ItemTemplateCreatorContinued.createItemTemplate(737, "Valrei mission item", "items", "excellent", "good", "ok", "poor",
* "A weird item belonging on Valrei.",
* new short[]{32, 59, 147, 60},
* 462, 1, 0, 86400, 3, 5, 50, -10, MiscConstants.EMPTY_BYTE_PRIMITIVE_ARRAY,
* "model.valrei.", 300.0f, 100, 21, 1, false);
*/
String name = "sorcery fragment [1/10]";
ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.fragment.sorcery");
itemBuilder.name(name, "sorcery fragments", "A scrap of a tome.");
itemBuilder.itemTypes(new short[]{
ItemTypes.ITEM_TYPE_MAGIC,
ItemTypes.ITEM_TYPE_FULLPRICE,
ItemTypes.ITEM_TYPE_NOSELLBACK,
ItemTypes.ITEM_TYPE_SERVERBOUND,
ItemTypes.ITEM_TYPE_ARTIFACT
});
itemBuilder.imageNumber((short) 331);
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.scrollbind.paper."); //model.valrei.magic
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(250);
itemBuilder.material(Materials.MATERIAL_CRYSTAL);
itemBuilder.value(5000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();
templateId = template.getTemplateId();
logger.info(name+" TemplateID: "+templateId);
}
}

View File

@@ -0,0 +1,44 @@
package mod.sin.items.caches;
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 TitanCache implements ItemTypes, MiscConstants {
public static Logger logger = Logger.getLogger(TitanCache.class.getName());
public static int templateId;
public void createTemplate() throws IOException{
String name = "titan cache";
ItemTemplateBuilder itemBuilder = new ItemTemplateBuilder("mod.item.cache.titan");
itemBuilder.name(name, "titan caches", "A cache of treasures from a titan.");
itemBuilder.itemTypes(new short[]{
ItemTypes.ITEM_TYPE_MAGIC,
ItemTypes.ITEM_TYPE_FULLPRICE,
ItemTypes.ITEM_TYPE_NOSELLBACK,
ItemTypes.ITEM_TYPE_ALWAYS_BANKABLE
});
itemBuilder.imageNumber((short) 243);
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.container.giftbox.");
itemBuilder.difficulty(5.0f);
itemBuilder.weightGrams(500);
itemBuilder.material(Materials.MATERIAL_GOLD);
itemBuilder.value(1000);
itemBuilder.isTraded(true);
ItemTemplate template = itemBuilder.build();
templateId = template.getTemplateId();
logger.info(name+" TemplateID: "+templateId);
}
}

View File

@@ -57,7 +57,7 @@ public class Club implements ItemTypes, MiscConstants {
logger.info("initCreationEntry()");
if(templateId > 0){
logger.info("Creating "+name+" creation entry, ID = "+templateId);
CreationEntryCreator.createSimpleEntry(SkillList.CARPENTRY_FINE, ItemList.knifeCarving, ItemList.log,
CreationEntryCreator.createSimpleEntry(SkillList.CARPENTRY, ItemList.knifeCarving, ItemList.log,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
//final AdvancedCreationEntry entry = CreationEntryCreator.createAdvancedEntry(SkillList.SMITHING_WEAPON_HEADS,
// ItemList.ironBand, ItemList.shaft, templateId, false, false, 0f, true, false, CreationCategories.TOOLS);

View File

@@ -57,17 +57,17 @@ public class Knuckles implements ItemTypes, MiscConstants {
logger.info("initCreationEntry()");
if(templateId > 0){
logger.info("Creating "+name+" creation entry, ID = "+templateId);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.brassBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.brassBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.ironBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.ironBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.steelBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.steelBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.adamantineBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.adamantineBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.glimmerSteelBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.glimmerSteelBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.anvilSmall, ItemList.seryllBar,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.anvilSmall, ItemList.seryllBar,
templateId, false, true, 0.0f, false, false, CreationCategories.WEAPONS);
//final AdvancedCreationEntry entry = CreationEntryCreator.createAdvancedEntry(SkillList.SMITHING_WEAPON_HEADS,
// ItemList.ironBand, ItemList.shaft, templateId, false, false, 0f, true, false, CreationCategories.TOOLS);

View File

@@ -59,7 +59,7 @@ public class Warhammer implements ItemTypes, MiscConstants {
logger.info("initCreationEntry()");
if(templateId > 0){
logger.info("Creating "+name+" creation entry, ID = "+templateId);
CreationEntryCreator.createSimpleEntry(SkillList.GROUP_SMITHING_WEAPONSMITHING, ItemList.shaft, WarhammerHead.templateId,
CreationEntryCreator.createSimpleEntry(SkillList.SMITHING_WEAPON_HEADS, ItemList.shaft, WarhammerHead.templateId,
templateId, true, true, 0.0f, false, false, CreationCategories.WEAPONS);
//final AdvancedCreationEntry entry = CreationEntryCreator.createAdvancedEntry(SkillList.SMITHING_WEAPON_HEADS,
// ItemList.ironBand, ItemList.shaft, templateId, false, false, 0f, true, false, CreationCategories.TOOLS);

View File

@@ -1,9 +1,16 @@
package mod.sin.wyvern;
import java.nio.ByteBuffer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Set;
import java.util.logging.Logger;
import com.wurmonline.server.skills.SkillList;
import mod.sin.lib.Util;
import mod.sin.wyvern.bounty.PlayerBounty;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
@@ -25,14 +32,47 @@ import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
public class AntiCheat {
private static Logger logger = Logger.getLogger(AntiCheat.class.getName());
private static final int emptyRock = Tiles.encode((short)-100, (byte)Tiles.Tile.TILE_CAVE_WALL.id, (byte)0);
public static void mapPlayerSteamId(String name, String steamId){
Connection dbcon;
PreparedStatement ps;
boolean foundSteamIdMap = false;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM SteamIdMap");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (!rs.getString("NAME").equals(name)) continue;
foundSteamIdMap = true;
}
rs.close();
ps.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (!foundSteamIdMap) {
logger.info("No steam id entry for " + name + ". Creating one.");
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("INSERT INTO SteamIdMap (NAME, STEAMID) VALUES(\"" + name + "\", " + steamId + ")");
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
PlayerBounty.steamIdMap.put(name, Long.valueOf(steamId));
}
private static boolean isCaveWall(int xx, int yy){
if (xx < 0 || xx >= Zones.worldTileSizeX || yy < 0 || yy >= Zones.worldTileSizeY) {
return true;
} else if (Tiles.isSolidCave((byte)Tiles.decodeType((int)Server.caveMesh.data[xx | yy << Constants.meshSize]))) {
} else if (Tiles.isSolidCave(Tiles.decodeType(Server.caveMesh.data[xx | yy << Constants.meshSize]))) {
return true;
}
return false;
@@ -57,9 +97,24 @@ public class AntiCheat {
return false;
}
return true;
}
private static boolean playerCanSeeVein(int tilex, int tiley, int distance){
int xx = tilex-distance;
int yy;
while(xx <= tilex+distance){
yy = tiley-distance;
while(yy <= tiley+distance){
if(!isCaveWall(xx, yy)){
return true;
}
yy++;
}
xx++;
}
return false;
}
private static int getDummyWallAntiCheat(int tilex, int tiley){
return Tiles.encode((short)Tiles.decodeHeight((int)Server.caveMesh.data[tilex | tiley << Constants.meshSize]), (byte)Tiles.Tile.TILE_CAVE_WALL.id, (byte)Tiles.decodeData((int)Server.caveMesh.data[tilex | tiley << Constants.meshSize]));
return Tiles.encode(Tiles.decodeHeight(Server.caveMesh.data[tilex | tiley << Constants.meshSize]), Tiles.Tile.TILE_CAVE_WALL.id, Tiles.decodeData((int)Server.caveMesh.data[tilex | tiley << Constants.meshSize]));
}
public static void sendCaveStripAntiCheat(Communicator comm, short xStart, short yStart, int width, int height){
if (comm.player != null && comm.player.hasLink()) {
@@ -73,6 +128,8 @@ public class AntiCheat {
bb.putShort((short)width);
bb.putShort((short)height);
boolean onSurface = comm.player.isOnSurface();
double prospecting = comm.player.getSkills().getSkill(SkillList.PROSPECT).getKnowledge();
int distance = (int) prospecting / 18;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
int xx = xStart + x;
@@ -82,12 +139,20 @@ public class AntiCheat {
xx = 0;
yy = 0;
} else if (!onSurface) {
if(!(Tiles.decodeType((int)Server.caveMesh.getTile(xx, yy)) == Tiles.Tile.TILE_CAVE_EXIT.id) && isSurroundedByCaveWalls(xx, yy)){
if(!(Tiles.decodeType(Server.caveMesh.getTile(xx, yy)) == Tiles.Tile.TILE_CAVE_EXIT.id)){
if(prospecting < 20 && isSurroundedByCaveWalls(xx, yy)){
bb.putInt(getDummyWallAntiCheat(xx, yy));
}else if(prospecting > 20 && playerCanSeeVein(xx, yy, distance)){
bb.putInt(Server.caveMesh.data[xx | yy << Constants.meshSize]);
}else if(!isSurroundedByCaveWalls(xx, yy)){
bb.putInt(Server.caveMesh.data[xx | yy << Constants.meshSize]);
}else {
bb.putInt(getDummyWallAntiCheat(xx, yy));
}
}else{
bb.putInt(Server.caveMesh.data[xx | yy << Constants.meshSize]);
}
} else if (Tiles.isSolidCave((byte)Tiles.decodeType((int)Server.caveMesh.data[xx | yy << Constants.meshSize]))) {
} else if (Tiles.isSolidCave(Tiles.decodeType(Server.caveMesh.data[xx | yy << Constants.meshSize]))) {
bb.putInt(getDummyWallAntiCheat(xx, yy));
} else {
bb.putInt(Server.caveMesh.data[xx | yy << Constants.meshSize]);
@@ -123,7 +188,7 @@ public class AntiCheat {
double dx = (double)(targetHeight - initialHeight) / dist;
while (!path.isEmpty()) {
PathTile p = path.getFirst();
if(Tiles.getTile((byte)Tiles.decodeType((int)p.getTile())).isTree()){
if(Tiles.getTile(Tiles.decodeType(p.getTile())).isTree()){
trees++;
}
/*if (Tiles.getTile((byte)Tiles.decodeType((int)p.getTile())).isTree() && treetilex == -1 && Server.rand.nextInt(10) < ++trees) {
@@ -200,15 +265,24 @@ public class AntiCheat {
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
Class<AntiCheat> thisClass = AntiCheat.class;
String replace;
// - Change the caveStrip method to the custom one, so we can edit what the clients see! - //
CtClass ctCommunicator = classPool.get("com.wurmonline.server.creatures.Communicator");
ctCommunicator.getDeclaredMethod("sendCaveStrip").setBody("{"
replace = "{ mod.sin.wyvern.AntiCheat.sendCaveStripAntiCheat(this, $$); }";
Util.setBodyDeclared(thisClass, ctCommunicator, "sendCaveStrip", replace);
/*ctCommunicator.getDeclaredMethod("sendCaveStrip").setBody("{"
+ " mod.sin.wyvern.AntiCheat.sendCaveStripAntiCheat(this, $$);"
+ "}");
+ "}");*/
Util.setReason("Map Steam ID's to Modsupport table.");
CtClass ctLoginHandler = classPool.get("com.wurmonline.server.LoginHandler");
replace = AntiCheat.class.getName()+".mapPlayerSteamId($1, $2);";
Util.insertBeforeDeclared(thisClass, ctLoginHandler, "preValidateLogin", replace);
// - Change the creature isVisibleTo method to the custom one, so we can edit what the clients see! - //
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
/*CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
ctCreature.getDeclaredMethod("isVisibleTo").setBody("{"
+ " return mod.sin.wyvern.AntiCheat.isVisibleToAntiCheat(this, $$);"
+ "}");
@@ -219,11 +293,11 @@ public class AntiCheat {
+ "if(!this.covers($1.getTileX(), $1.getTileY())){"
+ " return false;"
+ "}"
+ "if(!mod.sin.wyvern.AntiCheat.isVisibleToAntiCheat($1, this.watcher)){"
+ "if(!mod.sin.wyvern.AntiCheat.isVisibleToAntiCheat(this.watcher, $1)){"
+ " return false;"
+ "}");
+ "}");*/
} catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) {
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException((Throwable)e);
}
}

View File

@@ -0,0 +1,755 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.*;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.Creatures;
import com.wurmonline.server.creatures.MineDoorPermission;
import com.wurmonline.server.creatures.SpellEffects;
import com.wurmonline.server.economy.Economy;
import com.wurmonline.server.epic.Hota;
import com.wurmonline.server.items.*;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.questions.NewSpawnQuestion;
import com.wurmonline.server.questions.SpawnQuestion;
import com.wurmonline.server.spells.SpellEffect;
import com.wurmonline.server.villages.Citizen;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.zones.AreaSpellEffect;
import com.wurmonline.server.zones.VolaTile;
import com.wurmonline.server.zones.Zone;
import com.wurmonline.server.zones.Zones;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.creatures.titans.*;
import mod.sin.items.AffinityOrb;
import mod.sin.items.KeyFragment;
import mod.sin.items.caches.*;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import org.nyxcode.wurm.discordrelay.DiscordRelay;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;
public class Arena {
public static Logger logger = Logger.getLogger(Arena.class.getName());
public static byte getArenaAttitude(Player player, Creature aTarget){
if (player.getPower() > 0) {
if (player.getPower() >= 5) {
return 6;
}
return 3;
}
if (player == aTarget){
return 1;
}
if (player.opponent == aTarget) {
return 2;
}
if (player.getSaveFile().pet != -10 && aTarget.getWurmId() == player.getSaveFile().pet) {
return 1;
}
if (aTarget.getDominator() != null && aTarget.getDominator() != player) {
return player.getAttitude(aTarget.getDominator());
}
if (aTarget.isReborn() && player.getKingdomTemplateId() == 3) {
return 0;
}
if (aTarget.hasAttackedUnmotivated() && (aTarget.isPlayer() || !aTarget.isDominated() || aTarget.getDominator() != player)) {
return 2;
}
if (aTarget.citizenVillage != null && player.citizenVillage != null) {
if (player.citizenVillage.isCitizen(aTarget)) {
return 1;
}
if (player.citizenVillage.isAlly(aTarget)) {
return 1;
}
}
if (aTarget.isPlayer() && player.getTeam() != null && player.getTeam().contains(aTarget)){
return 1;
}
if (aTarget.isPlayer() && player.isFriend(aTarget.getWurmId())) {
return 1;
}
if (aTarget.isPlayer()){
return 2;
}
if (aTarget.isAggHuman()) {
return 2;
}
return 0;
}
public static void sendNewSpawnQuestion(SpawnQuestion sq){
NewSpawnQuestion nsq = new NewSpawnQuestion(sq.getResponder(), "Respawn", "Where would you like to spawn?", sq.getResponder().getWurmId());
nsq.sendQuestion();
}
public static void sendHotaMessage(String message){
DiscordRelay.sendToDiscord("arena", message, true);
}
public static void createNewHotaPrize(Village v, int winStreak){
try {
Item lump;
int x;
Item statue = ItemFactory.createItem(ItemList.statueHota, 99.0f, null);
byte material = Materials.MATERIAL_GOLD;
if (winStreak > 30) {
material = Materials.MATERIAL_ADAMANTINE;
}else if (winStreak > 20) {
material = Materials.MATERIAL_GLIMMERSTEEL;
}else if (winStreak > 10) {
material = Materials.MATERIAL_DIAMOND;
}else if (winStreak > 5) {
material = Materials.MATERIAL_CRYSTAL;
}
statue.setMaterial(material);
float posX = v.getToken().getPosX() - 2.0f + Server.rand.nextFloat() * 4.0f;
float posY = v.getToken().getPosY() - 2.0f + Server.rand.nextFloat() * 4.0f;
statue.setPosXYZRotation(posX, posY, Zones.calculateHeight(posX, posY, true), Server.rand.nextInt(350));
for (int i = 0; i < winStreak; ++i) {
if (i / 11 == winStreak % 11) {
statue.setAuxData((byte) 0);
statue.setData1(1);
continue;
}
statue.setAuxData((byte)winStreak);
}
int r = winStreak * 50 & 255;
int g = 0;
int b = 0;
if (winStreak > 5 && winStreak < 16) {
r = 0;
}
if (winStreak > 5 && winStreak < 20) {
g = winStreak * 50 & 255;
}
if (winStreak > 5 && winStreak < 30) {
b = winStreak * 50 & 255;
}
statue.setColor(WurmColor.createColor(r, g, b));
statue.getColor();
Zone z = Zones.getZone(statue.getTileX(), statue.getTileY(), true);
int numHelpers = 0;
for (Citizen c : v.citizens.values()) {
if (Hota.getHelpValue(c.getId()) <= 0) continue;
++numHelpers;
}
numHelpers = Math.min(5, numHelpers);
for (x = 0; x < numHelpers; ++x) {
Item sleepPowder = ItemFactory.createItem(ItemList.sleepPowder, 99f, null);
statue.insertItem(sleepPowder, true);
}
for (x = 0; x < 5; ++x) {
lump = ItemFactory.createItem(ItemList.adamantineBar, Math.min(99, 50 + winStreak), null);
float baseWeight = lump.getWeightGrams();
float multiplier = 1f+(winStreak*0.4f*Server.rand.nextFloat());
lump.setWeight((int) (baseWeight*multiplier), true);
statue.insertItem(lump, true);
}
for (x = 0; x < 5; ++x) {
lump = ItemFactory.createItem(ItemList.glimmerSteelBar, Math.min(99, 50 + winStreak), null);
float baseWeight = lump.getWeightGrams();
float multiplier = 1f+(winStreak*0.2f*Server.rand.nextFloat());
lump.setWeight((int) (baseWeight*multiplier), true);
statue.insertItem(lump, true);
}
// Key fragment
Item keyFragment = ItemFactory.createItem(KeyFragment.templateId, 99f, null);
statue.insertItem(keyFragment, true);
// Add affinity orb
Item affinityOrb = ItemFactory.createItem(AffinityOrb.templateId, 99f, null);
statue.insertItem(affinityOrb, true);
// Add 5 medium-quality caches
int[] cacheIds = {
ArtifactCache.templateId,
CrystalCache.templateId, CrystalCache.templateId,
DragonCache.templateId, DragonCache.templateId, DragonCache.templateId,
GemCache.templateId,
RiftCache.templateId, RiftCache.templateId, RiftCache.templateId,
TreasureMapCache.templateId
};
int i = 5+Server.rand.nextInt(4); // 5-8 caches.
while(i > 0){
Item cache = ItemFactory.createItem(cacheIds[Server.rand.nextInt(cacheIds.length)], 40f+(50f*Server.rand.nextFloat()), "");
statue.insertItem(cache, true);
i--;
}
i = 10+Server.rand.nextInt(11); // 10 - 20 kingdom tokens
while(i > 0){
Item token = ItemFactory.createItem(22765, 40f+(50f*Server.rand.nextFloat()), "");
statue.insertItem(token, true);
i--;
}
// Add 3-5 seryll lumps of medium ql
i = 3+Server.rand.nextInt(3); // 3-5 caches
while(i > 0){
Item seryll = ItemFactory.createItem(ItemList.seryllBar, 30f+(40f*Server.rand.nextFloat()), null);
statue.insertItem(seryll, true);
i--;
}
// Add 2-4 silver
long iron = 20000; // 2 silver
iron += Server.rand.nextInt(20000); // add up to 2 more silver
Item[] coins = Economy.getEconomy().getCoinsFor(iron);
for(Item coin : coins){
statue.insertItem(coin, true);
}
z.addItem(statue);
}
catch (Exception ex) {
logger.warning(ex.getMessage());
}
}
public static void respawnPlayer(Creature player, ServerEntry server){
ServerEntry targetserver = server.serverWest;
if(player instanceof Player){
Player p = (Player) player;
int tilex = targetserver.SPAWNPOINTJENNX;
int tiley = targetserver.SPAWNPOINTJENNY;
p.sendTransfer(Server.getInstance(), targetserver.INTRASERVERADDRESS, Integer.parseInt(targetserver.INTRASERVERPORT), targetserver.INTRASERVERPASSWORD, targetserver.id, tilex, tiley, true, false, p.getKingdomId());
}
}
public static void preInit(){
try {
ClassPool classPool = HookManager.getInstance().getClassPool();
Class<Arena> thisClass = Arena.class;
String replace;
// - Allow horse gear to be added/removed from horses without branding or taming (PvP Only) - //
CtClass ctCommunicator = classPool.get("com.wurmonline.server.creatures.Communicator");
replace = "if(com.wurmonline.server.Servers.isThisAPvpServer() && owner.getDominator() != this.player){"
+ " $_ = owner.getLeader();"
+ "}else{"
+ " if(this.player.getPower() > 0){"
+ " $_ = this.player;"
+ " }else{"
+ " $_ = $proceed($$);"
+ " }"
+ "}";
Util.instrumentDeclared(thisClass, ctCommunicator, "reallyHandle_CMD_MOVE_INVENTORY", "getDominator", replace);
/*ctCommunicator.getDeclaredMethod("reallyHandle_CMD_MOVE_INVENTORY").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getDominator")) {
m.replace("if(com.wurmonline.server.Servers.isThisAPvpServer() && owner.getDominator() != this.player){"
+ " $_ = owner.getLeader();"
+ "}else{"
+ " if(this.player.getPower() > 0){"
+ " $_ = this.player;"
+ " }else{"
+ " $_ = $proceed($$);"
+ " }"
+ "}");
return;
}
}
});*/
// - Allow lockpicking on PvP server, as well as treasure chests on PvE - //
CtClass ctItemBehaviour = classPool.get("com.wurmonline.server.behaviours.ItemBehaviour");
CtClass ctAction = classPool.get("com.wurmonline.server.behaviours.Action");
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
CtClass ctItem = classPool.get("com.wurmonline.server.items.Item");
CtClass[] params1 = {
ctAction,
ctCreature,
ctItem,
ctItem,
CtClass.shortType,
CtClass.floatType
};
String desc1 = Descriptor.ofMethod(CtClass.booleanType, params1);
Util.setReason("Allow lockpicking on the PvP server and improve PvE treasure chest lockpicking.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = true;"
+ "}else{"
+ " $_ = target.getLastOwnerId() == -10 || target.getLastOwnerId() == 0 || target.getTemplateId() == 995;"
+ "}";
Util.instrumentDescribed(thisClass, ctItemBehaviour, "action", desc1, "isInPvPZone", replace);
CtClass ctMethodsItems = classPool.get("com.wurmonline.server.behaviours.MethodsItems");
replace = "$_ = $proceed($$);"
+ "if($_ == -10 || $_ == 0){ ok = true; }";
Util.instrumentDeclared(thisClass, ctMethodsItems, "picklock", "getLastOwnerId", replace);
/*ctMethodsItems.getDeclaredMethod("picklock").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getLastOwnerId")) {
m.replace("$_ = $proceed($$);"
+ "if($_ == -10 || $_ == 0){ ok = true; }");
return;
}
}
});*/
// - Disable villages and PMK's on the PvP server - //
CtClass ctVillageFoundationQuestion = classPool.get("com.wurmonline.server.questions.VillageFoundationQuestion");
Util.setReason("Allow placing deed outside of kingdom border.");
replace = "$_ = (byte) 4;";
Util.instrumentDeclared(thisClass, ctVillageFoundationQuestion, "checkSize", "getKingdom", replace);
CtClass ctKingdomFoundationQuestion = classPool.get("com.wurmonline.server.questions.KingdomFoundationQuestion");
Util.setReason("Disable PMK's on the Arena server.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " this.getResponder().getCommunicator().sendSafeServerMessage(\"Player-Made Kingdoms are disabled on this server.\");"
+ " return;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctKingdomFoundationQuestion, "sendQuestion", replace);
// - Disable champion players altogether - //
CtClass ctRealDeathQuestion = classPool.get("com.wurmonline.server.questions.RealDeathQuestion");
Util.setReason("Disable player champions.");
replace = "this.getResponder().getCommunicator().sendSafeServerMessage(\"Champion players are disabled on this server.\");"
+ "return;";
Util.insertBeforeDeclared(thisClass, ctRealDeathQuestion, "sendQuestion", replace);
// - Re-sort player aggression on the PvP server - //
CtClass ctPlayer = classPool.get("com.wurmonline.server.players.Player");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " return "+Arena.class.getName()+".getArenaAttitude(this, $1);"
+ "}";
Util.insertBeforeDeclared(thisClass, ctPlayer, "getAttitude", replace);
Util.setReason("Re-sort creature-player aggression on the PvP server.");
replace = "" +
"if(com.wurmonline.server.Servers.localServer.PVPSERVER && ($1.isPlayer() || this.isPlayer())){" +
" if($1.citizenVillage != null && this.citizenVillage != null){" +
" if($1.citizenVillage == this.citizenVillage){" +
" return 1;" +
" }" +
" if($1.citizenVillage.isAlly(this.citizenVillage)){" +
" return 1;" +
" }" +
" }" +
"}";
Util.insertBeforeDeclared(thisClass, ctCreature, "getAttitude", replace);
// - Hook for (ENEMY) declaration to allow for enemy presence blocking - //
CtClass ctVirtualZone = classPool.get("com.wurmonline.server.zones.VirtualZone");
CtClass[] params2 = {
CtClass.longType,
CtClass.booleanType,
CtClass.longType,
CtClass.floatType,
CtClass.floatType,
CtClass.floatType
};
String desc2 = Descriptor.ofMethod(CtClass.booleanType, params2);
replace = "if(this.watcher.isPlayer() && creature.isPlayer()){" +
" if("+PlayerTitles.class.getName()+".hasCustomTitle(creature)){" +
" suff = suff + "+PlayerTitles.class.getName()+".getCustomTitle(creature);" +
" }" +
" if(com.wurmonline.server.Servers.localServer.PVPSERVER && "+Arena.class.getName()+".getArenaAttitude((com.wurmonline.server.players.Player)this.watcher, creature) == 2){"
+ " suff = suff + \" (ENEMY)\";"
+ " enemy = true;" +
" }"
+ "}"
+ "$_ = $proceed($$);";
Util.instrumentDescribed(thisClass, ctVirtualZone, "addCreature", desc2, "isChampion", replace);
// - Modify when an enemy is present or not to use attitude instead of kingdom - //
replace = "if(this.watcher.isPlayer() && creature.isPlayer() && com.wurmonline.server.Servers.localServer.PVPSERVER && "+Arena.class.getName()+".getArenaAttitude((com.wurmonline.server.players.Player)this.watcher, creature) == 2){"
+ " $_ = 1;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctVirtualZone, "checkIfEnemyIsPresent", "getKingdomId", replace);
/*ctVirtualZone.getDeclaredMethod("checkIfEnemyIsPresent").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getKingdomId")) {
m.replace("if(this.watcher.isPlayer() && creature.isPlayer() && com.wurmonline.server.Servers.localServer.PVPSERVER && mod.sin.wyvern.Arena.getArenaAttitude((com.wurmonline.server.players.Player)this.watcher, creature) == 2){"
+ " $_ = 1;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}");
return;
}
}
});*/
// - Block twigs and stones on the PvP server - //
CtClass ctMethodsCreatures = classPool.get("com.wurmonline.server.behaviours.MethodsCreatures");
Util.setReason("Block farwalker twigs and stones on PvP.");
replace = "$_ = com.wurmonline.server.Servers.localServer.PVPSERVER;";
Util.instrumentDeclared(thisClass, ctMethodsCreatures, "teleportCreature", "isInPvPZone", replace);
/*ctMethodsCreatures.getDeclaredMethod("teleportCreature").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isInPvPZone")) {
m.replace("$_ = com.wurmonline.server.Servers.localServer.PVPSERVER;");
return;
}
}
});*/
// - After respawn on PvP, send directly to PvE server - //
/*CtClass ctSpawnQuestion = classPool.get("com.wurmonline.server.questions.SpawnQuestion");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " "+Arena.class.getName()+".respawnPlayer(this.getResponder(), com.wurmonline.server.Servers.localServer);"
+ " return;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctSpawnQuestion, "sendQuestion", replace);*/
/*ctSpawnQuestion.getDeclaredMethod("sendQuestion").insertBefore(""
+ "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " mod.sin.wyvern.Arena.respawnPlayer(this.getResponder(), com.wurmonline.server.Servers.localServer);"
+ " return;"
+ "}");*/
// - Allow affinity stealing and battle rank changes - //
Util.setReason("Allow affinity stealing and battle rank changes.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = true;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctPlayer, "modifyRanking", "isEnemyOnChaos", replace);
//CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
Util.setReason("Increase fight skill gain on PvP server.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " p.getFightingSkill().setKnowledge(pskill + (skillGained*1.5d), false);"
+ "}"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCreature, "modifyFightSkill", "checkInitialTitle", replace);
// - Fix nearby enemy check to find aggression instead of kingdom - //
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = c.getAttitude(performer) != 2 && c.getAttitude(performer) != 1;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctMethodsItems, "isEnemiesNearby", "isFriendlyKingdom", replace);
/*ctMethodsItems.getDeclaredMethod("isEnemiesNearby").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isFriendlyKingdom")) {
m.replace("if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = c.getAttitude(performer) != 2;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}");
return;
}
}
});*/
// - Ensure corpses are not loot protected on PvP - //
Util.setReason("Ensure corpses are not loot protected.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = $proceed(false);"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "setProtected", replace);
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " $_ = true;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "isInPvPZone", replace);
// - Allow players to do actions in PvP houses - //
CtClass ctMethods = classPool.get("com.wurmonline.server.behaviours.Methods");
Util.setReason("Enable players to do actions in PvP houses.");
replace = "$_ = com.wurmonline.server.Servers.localServer.PVPSERVER;";
Util.instrumentDeclared(thisClass, ctMethods, "isNotAllowedMessage", "isEnemy", replace);
// - Allow stealing against deity wishes without being punished on Arena - //
//CtClass ctAction = classPool.get("com.wurmonline.server.behaviours.Action");
Util.setReason("Allow stealing against deity wishes without being punished.");
replace = "$_ = $proceed($$) || com.wurmonline.server.Servers.localServer.PVPSERVER;";
Util.instrumentDeclared(thisClass, ctAction, "checkLegalMode", "isLibila", replace);
/*ctAction.getDeclaredMethod("checkLegalMode").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isLibila")) {
m.replace("$_ = $proceed($$) || com.wurmonline.server.Servers.localServer.PVPSERVER;");
return;
}
}
});*/
// - Allow taking ownership of vehicles on Arena - //
// TODO: Fix.
Util.setReason("Allow taking ownership of vehicles on Arena.");
CtClass[] params3 = new CtClass[]{
CtClass.longType,
CtClass.booleanType,
CtClass.byteType,
CtClass.intType,
CtClass.intType
};
String desc3 = Descriptor.ofMethod(CtClass.voidType, params3);
replace = "$_ = com.wurmonline.server.Servers.localServer.PVPSERVER && !lVehicle.isLocked();";
Util.instrumentDescribed(thisClass, ctCreature, "setVehicle", desc3, "isThisAChaosServer", replace);
// - Allow managing animals on Arena - //
CtClass ctManageMenu = classPool.get("com.wurmonline.server.behaviours.ManageMenu");
replace = "$_ = false;";
Util.instrumentDeclared(thisClass, ctManageMenu, "getBehavioursFor", "isThisAPvpServer", replace);
Util.instrumentDeclared(thisClass, ctManageMenu, "action", "isThisAPvpServer", replace);
// - Multiply mine door bash damage by 3 on Arena - //
CtClass ctTerraforming = classPool.get("com.wurmonline.server.behaviours.Terraforming");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " damage *= 3d;"
+ "}"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctTerraforming, "destroyMineDoor", "getOrCreateTile", replace);
/*ctTerraforming.getDeclaredMethod("destroyMineDoor").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getOrCreateTile")) {
m.replace("if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " damage *= 3d;"
+ "}"
+ "$_ = $proceed($$);");
return;
}
}
});*/
// - Prevent tons of errors for legality on Arena. - //
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " return true;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctCreature, "isOkToKillBy", replace);
/*ctCreature.getDeclaredMethod("isOkToKillBy").insertBefore(""
+ "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " return true;"
+ "}");*/
Util.insertBeforeDeclared(thisClass, ctCreature, "hasBeenAttackedBy", replace);
/*ctCreature.getDeclaredMethod("hasBeenAttackedBy").insertBefore(""
+ "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " return true;"
+ "}");*/
// - Disable CA Help on Arena - //
Util.setReason("Disable CA HELP on Arena.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " return false;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctPlayer, "seesPlayerAssistantWindow", replace);
Util.setReason("Make players who are non-allied enemies of villages.");
CtClass ctVillage = classPool.get("com.wurmonline.server.villages.Village");
CtClass[] params4 = new CtClass[]{
ctCreature,
CtClass.booleanType
};
String desc4 = Descriptor.ofMethod(CtClass.booleanType, params4);
replace = "" +
"if(com.wurmonline.server.Servers.localServer.PVPSERVER && $1.isPlayer()){" +
" if($1.getPower() > 0){" +
" return false;" +
" }" +
" if(this.isCitizen($1) || this.isAlly($1)){" +
" return false;" +
" }" +
" return true;" +
"}" +
// Additional code added to ensure village guards do not attack titans or rare creatures.
"if("+Titans.class.getName()+".isTitan($1) || "+RareSpawns.class.getName()+".isRareCreature($1)){" +
" return false;" +
"}";
Util.insertBeforeDescribed(thisClass, ctVillage, "isEnemy", desc4, replace);
Util.setReason("Make all deeds enemies of eachother unless allied.");
CtClass[] params5 = new CtClass[]{
ctVillage
};
String desc5 = Descriptor.ofMethod(CtClass.booleanType, params5);
replace = "{ if($1 == null){" +
" return false;" +
" }" +
" if($1.kingdom != this.kingdom){" +
" return true;" +
" }" +
" if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" if(this.isAlly($1)){" +
" return false;" +
" }" +
" if($0 == $1){" +
" return false;" +
" }" +
" return true;" +
"}" +
"return false; }";
Util.setBodyDescribed(thisClass, ctVillage, "isEnemy", desc5, replace);
Util.setReason("Change HotA reward");
replace = Arena.class.getName()+".createNewHotaPrize(this, $1);";
Util.setBodyDeclared(thisClass, ctVillage, "createHotaPrize", replace);
CtClass ctGuardPlan = classPool.get("com.wurmonline.server.villages.GuardPlan");
CtClass[] params6 = new CtClass[]{
CtClass.intType,
CtClass.intType
};
String desc6 = Descriptor.ofMethod(CtClass.intType, params6);
Util.setReason("Cap maximum guards to 5.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" return Math.min(5, Math.max(3, $1 * $2 / 49));" +
"}";
Util.insertBeforeDescribed(thisClass, ctGuardPlan, "getMaxGuards", desc6, replace);
Util.setReason("Disable towers");
CtClass ctAdvancedCreationEntry = classPool.get("com.wurmonline.server.items.AdvancedCreationEntry");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" performer.getCommunicator().sendAlertServerMessage(\"Towers are disabled for now. A new system is in progress.\");" +
" throw new com.wurmonline.server.NoSuchItemException(\"Towers are disabled.\");" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctAdvancedCreationEntry, "cont", "isTowerTooNear", replace);
Util.instrumentDeclared(thisClass, ctAdvancedCreationEntry, "run", "isTowerTooNear", replace);
Util.setReason("Reduce local range (player).");
replace = "if($3 > 5){" +
" $_ = $proceed($1, $2, 50);" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctVirtualZone, "coversCreature", "isWithinDistanceTo", replace);
Util.setReason("Reduce local range (creature).");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctVirtualZone, "coversCreature", "isPlayer", replace);
CtClass ctKarmaQuestion = classPool.get("com.wurmonline.server.questions.KarmaQuestion");
Util.setReason("Disable Karma teleport.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" $_ = true;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctKarmaQuestion, "answer", "isInPvPZone", replace);
Util.setReason("Make players only able to lead one creature.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" return this.followers == null || this.followers.size() < 1;" +
"}";
Util.insertBeforeDeclared(thisClass, ctPlayer, "mayLeadMoreCreatures", replace);
CtClass ctMethodsStructure = classPool.get("com.wurmonline.server.behaviours.MethodsStructure");
Util.setReason("Increase bash timer to 15 seconds.");
replace = "time = 600;" +
"$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctMethodsStructure, "destroyWall", "getStructure", replace);
CtClass ctHota = classPool.get("com.wurmonline.server.epic.Hota");
Util.setReason("Display discord message for HotA announcements.");
replace = Arena.class.getName()+".sendHotaMessage($1);" +
"$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctHota, "poll", "broadCastSafe", replace);
Util.setReason("Display discord message for HotA wins.");
Util.instrumentDeclared(thisClass, ctHota, "win", "broadCastSafe", replace);
Util.setReason("Display discord message for HotA conquers & neutralizes.");
replace = "if($2.getData1() == 0){" +
" "+Arena.class.getName()+".sendHotaMessage($1.getName() + \" neutralizes the \" + $2.getName() + \".\");" +
"}else{" +
" "+Arena.class.getName()+".sendHotaMessage($1.getName() + \" conquers the \" + $2.getName() + \".\");" +
"}";
Util.insertBeforeDeclared(thisClass, ctHota, "addPillarConquered", replace);
// handle_TARGET_and_TARGET_HOSTILE
CtClass ctCreatureBehaviour = classPool.get("com.wurmonline.server.behaviours.CreatureBehaviour");
Util.setReason("Allow players to attack enemy guards.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" $_ = false;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCreatureBehaviour, "handle_TARGET_and_TARGET_HOSTILE", "isFriendlyKingdom", replace);
Util.setReason("Fix templars attacking themselves.");
replace = "if($1.isSpiritGuard()){" +
" return;" +
"}";
Util.insertBeforeDeclared(thisClass, ctVillage, "addTarget", replace);
Util.setReason("Keep mine doors open for shorter durations.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctCreature, "checkOpenMineDoor", "isThisAChaosServer", replace);
Util.setReason("Fix fight skill gains against enemy players.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" if($0 == this){" +
" $_ = -1;" +
" }else{" +
" $_ = $proceed($$);" +
" }" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCreature, "modifyFightSkill", "getKingdomId", replace);
Util.setReason("Enable archering enemies on deeds.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctVillage, "mayAttack", "isEnemyOnChaos", replace);
// Server.rand.nextFloat()*(35/(1-2*desiredPercent))
Util.setReason("Nerf magranon faith protection.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" $_ = com.wurmonline.server.Server.rand.nextInt(40);" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "getFavor", replace);
Util.setReason("Nerf resurrection stones.");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" $_ = com.wurmonline.server.Server.rand.nextInt(40) > 35;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "isDeathProtected", replace);
Util.setReason("Adjust spawn question mechanics.");
CtClass ctSpawnQuestion = classPool.get("com.wurmonline.server.questions.SpawnQuestion");
replace = "if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
Arena.class.getName()+".sendNewSpawnQuestion(this);" +
"return;" +
"}";
Util.insertBeforeDeclared(thisClass, ctSpawnQuestion, "sendQuestion", replace);
CtClass ctMeshIO = classPool.get("com.wurmonline.mesh.MeshIO");
CtClass[] params7 = new CtClass[]{
ctCreature,
ctItem,
CtClass.intType,
CtClass.intType,
CtClass.intType,
CtClass.floatType,
CtClass.booleanType,
ctMeshIO,
CtClass.booleanType
};
String desc7 = Descriptor.ofMethod(CtClass.booleanType, params7);
replace = Arena.class.getName()+".sendHotaMessage($1+\" \"+$2);" +
"$_ = $proceed($$);";
Util.instrumentDescribed(thisClass, ctTerraforming, "dig", desc7, "addHistory", replace);
// Creature performer, Item source, int tilex, int tiley, int tile, float counter, boolean corner, MeshIO mesh, boolean toPile
Util.setReason("Set favored kingdom for PvP");
CtClass ctDeities = classPool.get("com.wurmonline.server.deities.Deities");
replace = "{ return (byte) 4; }";
Util.setBodyDeclared(thisClass, ctDeities, "getFavoredKingdom", replace);
Util.setReason("Set favored kingdom for PvP");
CtClass ctDeity = classPool.get("com.wurmonline.server.deities.Deity");
replace = "{ return (byte) 4; }";
Util.setBodyDeclared(thisClass, ctDeities, "getFavoredKingdom", replace);
}catch (NotFoundException e) {
throw new HookException(e);
}
}
}

View File

@@ -23,10 +23,10 @@ import mod.sin.wyvern.bounty.PlayerBounty;
public class Bounty {
public static final Logger logger = Logger.getLogger(Bounty.class.getName());
//protected static WyvernMods mod;
public static HashMap<String, Integer> reward = new HashMap<String, Integer>();
public static HashMap<String, Integer> reward = new HashMap<>();
// Using a hook in CombatEngine.addWound, we call this function to create a list of creatures that actually inflicted damage.
public static HashMap<Long, Map<Long, Double>> dealtDamage = new HashMap<Long, Map<Long, Double>>();
public static HashMap<Long, Map<Long, Double>> dealtDamage = new HashMap<>();
public static void addDealtDamage(long defender, long attacker, double damage){
if(dealtDamage.containsKey(defender)){
Map<Long, Double> dealers = dealtDamage.get(defender);
@@ -38,7 +38,7 @@ public class Bounty {
dealers.put(attacker, newDam);
}
}else{
Map<Long, Double> dealers = new HashMap<Long, Double>();
Map<Long, Double> dealers = new HashMap<>();
dealers.put(attacker, damage);
dealtDamage.put(defender, dealers);
}
@@ -76,20 +76,24 @@ public class Bounty {
double weaponlessFighting = mob.getWeaponLessFightingSkill().getKnowledge();
double fs = Math.max(fighting, weaponlessFighting);
double bodyStr = mob.getBodyStrength().getKnowledge();
double cretStr = 2000D + ((double)combatRating*(double)maxDmg*Math.sqrt(fs)*bodyStr);
//double cretStr = 2000D + ((double)combatRating*(double)maxDmg*Math.sqrt(fs)*bodyStr);
//logger.info("pre-armour: "+cretStr);
//cretStr /= Math.max(mob.getArmourMod(), 0.001d);
fs /= mob.getArmourMod();
cretStr = 500D + ((double)combatRating*Math.cbrt(maxDmg)*Math.sqrt(fs)*Math.cbrt(bodyStr));
cretStr *= 2d;
double cretStr = 100D + (combatRating*Math.cbrt(maxDmg)*Math.cbrt(fs)*Math.cbrt(bodyStr));
cretStr *= 0.8d;
//logger.info("post-armour: "+cretStr);
//cretStr *= 1-(Math.min(Math.max(mob.getArmourMod(), 0.001d), 0.8f));
//cretStr = 2000D + ((double)combatRating*(double)maxDmg*Math.sqrt(fs)*bodyStr);
double k = 100000000d;
double k = 100000d;
cretStr = (cretStr*Math.pow(2, (-(cretStr/k)))+k*(1-Math.pow(2, -cretStr/k)))/(1+Math.pow(2, -cretStr/k));
if(cretStr < 500D){
if(mob.isAggHuman() && cretStr < 100D){
cretStr *= 1+(Server.rand.nextFloat()*0.2f);
cretStr = Math.max(cretStr, 500D);
cretStr = Math.max(cretStr, 100D);
}else if(!mob.isAggHuman() && cretStr < 300D){
cretStr *= 0.4f;
cretStr *= 1+(Server.rand.nextFloat()*0.2f);
cretStr = Math.max(cretStr, 10D);
}
//logger.info("capped: "+cretStr);
return cretStr;

View File

@@ -4,6 +4,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;
import com.wurmonline.server.MiscConstants;
import mod.sin.wyvern.util.ItemUtil;
import org.gotti.wurmunlimited.modsupport.actions.ModActions;
import com.pveplands.treasurehunting.Treasuremap;
@@ -29,7 +31,7 @@ import mod.sin.weapons.*;
public class Caches {
public static final Logger logger = Logger.getLogger(Caches.class.getName());
public static ArrayList<Integer> CACHE_IDS = new ArrayList<Integer>();
public static ArrayList<Integer> CACHE_IDS = new ArrayList<>();
public static AnimalCache ANIMAL_CACHE = new AnimalCache();
public static ArmourCache ARMOUR_CACHE = new ArmourCache();
@@ -40,31 +42,31 @@ public class Caches {
public static MoonCache MOON_CACHE = new MoonCache();
public static PotionCache POTION_CACHE = new PotionCache();
public static RiftCache RIFT_CACHE = new RiftCache();
public static TitanCache TITAN_CACHE = new TitanCache();
public static ToolCache TOOL_CACHE = new ToolCache();
public static TreasureMapCache TREASUREMAP_CACHE = new TreasureMapCache();
public static WeaponCache WEAPON_CACHE = new WeaponCache();
public static float minimumQuality = 10f;
public static boolean isTreasureCache(Item item){
int templateId = item.getTemplateId();
if(CACHE_IDS.contains(templateId)){
return true;
}
return false;
return CACHE_IDS.contains(templateId);
}
public static float getBaseQuality(float quality){
return quality*0.5f;
return quality*0.2f;
}
public static float getRandomQuality(float quality){
return quality*0.55f;
return quality*0.5f;
}
public static float getWeightMultiplier(int templateId, float quality){
if(templateId == DragonCache.templateId){
return (quality*0.005f)+(quality*0.001f*Server.rand.nextFloat());
return 0.005f+(quality*0.0005f)+(quality*0.0001f*Server.rand.nextFloat());
}else if(templateId == MoonCache.templateId){
return 1f+(quality*0.05f)+(quality*0.05f*Server.rand.nextFloat());
return 1f+(quality*0.005f)+(quality*0.005f*Server.rand.nextFloat());
}
return 1f+(quality*0.02f);
return 1f+(quality*0.002f);
}
public static boolean adjustBasicWeight(int templateId){
if(templateId == DragonCache.templateId){
@@ -74,21 +76,11 @@ public class Caches {
}
return false;
}
public static void applyEnchant(Item item, byte enchant, float power){
ItemSpellEffects effs = item.getSpellEffects();
if(effs == null){
effs = new ItemSpellEffects(item.getWurmId());
}
SpellEffect eff = new SpellEffect(item.getWurmId(), enchant, power, 20000000);
effs.addSpellEffect(eff);
if(item.getDescription().length() > 0){
item.setDescription(item.getDescription()+" ");
}
item.setDescription(item.getDescription()+eff.getName().substring(0,1)+Math.round(power));
}
public static boolean createsCustomBasic(int templateId){
if(templateId == TreasureMapCache.templateId){
if(templateId == TitanCache.templateId){
return true;
}else if(templateId == TreasureMapCache.templateId){
return true;
}
return false;
@@ -96,7 +88,16 @@ public class Caches {
public static void getCustomBasic(Creature performer, Item cache){
int templateId = cache.getTemplateId();
if(templateId == TreasureMapCache.templateId){
if(templateId == TitanCache.templateId){
Item efficiencyTool = ItemUtil.createRandomToolWeapon(20f, 40f, cache.getCreatorName());
ItemUtil.applyEnchant(efficiencyTool, (byte) 114, 40f+(20f*Server.rand.nextFloat())); // Efficiency enchant is 114
if(efficiencyTool.isMetal()){
efficiencyTool.setMaterial(Server.rand.nextBoolean() ? Materials.MATERIAL_ADAMANTINE : Materials.MATERIAL_GLIMMERSTEEL);
}else if(efficiencyTool.isWood()){
efficiencyTool.setMaterial(Materials.MATERIAL_WOOD_WILLOW);
}
performer.getInventory().insertItem(efficiencyTool, true);
}else if(templateId == TreasureMapCache.templateId){
Item map = Treasuremap.CreateTreasuremap(performer, cache, null, null, true);
map.setRarity(cache.getRarity());
performer.getInventory().insertItem(map, true);
@@ -117,7 +118,7 @@ public class Caches {
ItemList.axeSmall, ItemList.axeMedium, ItemList.axeHuge,
ItemList.maulSmall, ItemList.maulMedium, ItemList.maulLarge,
ItemList.spearLong, ItemList.staffSteel, ItemList.halberd,
Club.templateId, Knuckles.templateId, Warhammer.templateId
Knuckles.templateId, Warhammer.templateId
};
}else if(templateId == CrystalCache.templateId){
return new int[]{
@@ -129,8 +130,8 @@ public class Caches {
ItemList.drakeHide,
ItemList.drakeHide,
ItemList.dragonScale,
ItemList.dragonScale,
SpectralHide.templateId
ItemList.dragonScale
//SpectralHide.templateId
};
}else if(templateId == GemCache.templateId){
return new int[]{
@@ -142,8 +143,9 @@ public class Caches {
};
}else if(templateId == MoonCache.templateId){
return new int[]{
ItemList.glimmerSteelBar,
ItemList.adamantineBar
ItemList.glimmerSteelBar, ItemList.glimmerSteelBar, ItemList.glimmerSteelBar, ItemList.glimmerSteelBar, ItemList.glimmerSteelBar,
ItemList.adamantineBar, ItemList.adamantineBar, ItemList.adamantineBar, ItemList.adamantineBar, ItemList.adamantineBar,
ItemList.seryllBar
};
}else if(templateId == PotionCache.templateId){
return new int[]{
@@ -177,14 +179,14 @@ public class Caches {
if(templateId == ArmourCache.templateId){
if(quality > 50){
if(quality > 95 && Server.rand.nextBoolean()){
applyEnchant(item, Enchants.BUFF_SHARED_PAIN, quality*Server.rand.nextFloat()*1.2f);
applyEnchant(item, Enchants.BUFF_WEBARMOUR, quality*Server.rand.nextFloat()*1.2f);
ItemUtil.applyEnchant(item, Enchants.BUFF_SHARED_PAIN, quality*Server.rand.nextFloat()*0.7f);
ItemUtil.applyEnchant(item, Enchants.BUFF_WEBARMOUR, quality*Server.rand.nextFloat()*0.7f);
}else if(Server.rand.nextBoolean()){
byte[] armourEnchants = {
Enchants.BUFF_SHARED_PAIN,
Enchants.BUFF_WEBARMOUR
};
applyEnchant(item, armourEnchants[Server.rand.nextInt(armourEnchants.length)], quality*Server.rand.nextFloat()*1.5f);
ItemUtil.applyEnchant(item, armourEnchants[Server.rand.nextInt(armourEnchants.length)], quality*Server.rand.nextFloat()*1.5f);
}
}
if(quality > 80 && Server.rand.nextInt(4) == 0){
@@ -209,39 +211,41 @@ public class Caches {
byte[] materials = {
Materials.MATERIAL_ADAMANTINE,
Materials.MATERIAL_GLIMMERSTEEL,
Materials.MATERIAL_SERYLL,
Materials.MATERIAL_STEEL,
Materials.MATERIAL_STEEL
};
item.setMaterial(materials[Server.rand.nextInt(materials.length)]);
float qualBoost = (100f-item.getQualityLevel())*Server.rand.nextFloat();
item.setQualityLevel(item.getQualityLevel()+qualBoost);
if(quality > 50 && Server.rand.nextInt(200) < quality){
item.setQualityLevel(item.getQualityLevel());
if(Server.rand.nextInt(400) < quality){
if(item.getRarity() == 0){
if(Server.rand.nextInt(600) < quality){
item.setRarity((byte) 2);
if(Server.rand.nextInt(900) < quality){
item.setRarity(MiscConstants.SUPREME);
}else{
item.setRarity((byte) 1);
item.setRarity(MiscConstants.RARE);
}
}
}
if(quality > 70 && Server.rand.nextBoolean()){
if(Server.rand.nextBoolean()){
if(quality > 50 && Server.rand.nextBoolean()){
byte[] enchants = {
Enchants.BUFF_WIND_OF_AGES,
Enchants.BUFF_BLESSINGDARK
};
applyEnchant(item, enchants[Server.rand.nextInt(enchants.length)], quality*Server.rand.nextFloat()*0.9f);
applyEnchant(item, Enchants.BUFF_NIMBLENESS, quality*Server.rand.nextFloat()*1.2f);
}else{
applyEnchant(item, Enchants.BUFF_LIFETRANSFER, quality+(quality*Server.rand.nextFloat()));
}
ItemUtil.applyEnchant(item, enchants[Server.rand.nextInt(enchants.length)], quality*Server.rand.nextFloat()*0.6f);
ItemUtil.applyEnchant(item, Enchants.BUFF_NIMBLENESS, quality*Server.rand.nextFloat()*0.7f);
}else if(quality > 30){
ItemUtil.applyEnchant(item, Enchants.BUFF_LIFETRANSFER, quality*0.6f+(quality*0.6f*Server.rand.nextFloat()));
}
}else if(templateId == CrystalCache.templateId){
item.setQualityLevel(Server.rand.nextFloat()*quality);
if(Server.rand.nextInt(500) < quality){
item.setRarity(MiscConstants.RARE);
}
}
}
public static int getBasicNums(int templateId){
if(templateId == CrystalCache.templateId){
return 15;
return Server.rand.nextInt(5)+5;
}else if(templateId == GemCache.templateId){
return 2;
}
@@ -251,7 +255,7 @@ public class Caches {
if(templateId == ArmourCache.templateId){
return Server.rand.nextInt(2);
}else if(templateId == CrystalCache.templateId){
return Server.rand.nextInt(Math.max((int) (quality*0.3f), 2));
return Server.rand.nextInt(Math.max((int) (quality*0.08f), 2));
}else if(templateId == DragonCache.templateId){
if(Server.rand.nextInt(200) <= quality){
return 1;
@@ -272,17 +276,19 @@ public class Caches {
return 0;
}
public static int getExtraItemChance(int templateId){
if(templateId == ArmourCache.templateId){
/*if(templateId == ArmourCache.templateId){
return 1600;
}else if(templateId == DragonCache.templateId){
return 600;
}else*/ if(templateId == DragonCache.templateId){
return 500;
}else if(templateId == GemCache.templateId){
return 200;
return 150;
}else if(templateId == MoonCache.templateId){
return 500;
}
return -1;
}
public static int[] getExtraTemplates(int templateId){
if(templateId == ArmourCache.templateId){
/*if(templateId == ArmourCache.templateId){
return new int[]{
GlimmerscaleBoot.templateId,
GlimmerscaleGlove.templateId,
@@ -297,7 +303,7 @@ public class Caches {
SpectralJacket.templateId,
SpectralSleeve.templateId
};
}else if(templateId == DragonCache.templateId){
}else*/ if(templateId == DragonCache.templateId){
return new int[]{
ItemList.dragonLeatherBoot,
ItemList.dragonLeatherCap,
@@ -319,6 +325,23 @@ public class Caches {
ItemList.rubyStar,
ItemList.sapphireStar
};
}else if(templateId == MoonCache.templateId){
return new int[]{
ItemList.chainSleeve,
ItemList.chainJacket,
ItemList.chainHose,
ItemList.chainGlove,
ItemList.chainCoif,
ItemList.chainBoot,
ItemList.plateSleeve,
ItemList.plateJacket,
ItemList.plateHose,
ItemList.plateBoot,
ItemList.plateGauntlet,
ItemList.helmetOpen,
ItemList.helmetGreat,
ItemList.helmetBasinet
};
}
return null;
}
@@ -328,6 +351,8 @@ public class Caches {
item.setColor(WurmColor.createColor(100, 100, 100));
}else if(templateId == DragonCache.templateId){
item.setMaterial(Materials.MATERIAL_LEATHER);
}else if(templateId == MoonCache.templateId){
item.setMaterial(Server.rand.nextBoolean() ? Materials.MATERIAL_ADAMANTINE : Materials.MATERIAL_GLIMMERSTEEL);
}
}
@@ -351,7 +376,7 @@ public class Caches {
while(i < basicNums){
try {
float basicQuality = Math.max(baseQL+(randQL*Server.rand.nextFloat()), baseQL+(randQL*Server.rand.nextFloat()));
basicQuality = Math.min(basicQuality, 100f);
basicQuality = Math.min(minimumQuality+basicQuality, 100f);
Item basicItem = ItemFactory.createItem(basicTemplates[Server.rand.nextInt(basicTemplates.length)], basicQuality, "");
basicItem.setRarity(cache.getRarity());
adjustBasicItem(templateId, quality, basicItem);
@@ -373,7 +398,7 @@ public class Caches {
int[] extraTemplates = getExtraTemplates(templateId);
if(extraTemplates != null){
float extraQuality = Math.max(baseQL+(randQL*Server.rand.nextFloat()), baseQL+(randQL*Server.rand.nextFloat()));
extraQuality = Math.min(extraQuality, 100f);
extraQuality = Math.min(minimumQuality+extraQuality, 100f);
Item extraItem = ItemFactory.createItem(extraTemplates[Server.rand.nextInt(extraTemplates.length)], extraQuality, "");
extraItem.setRarity(cache.getRarity());
adjustExtraItem(templateId, extraItem);
@@ -406,6 +431,8 @@ public class Caches {
CACHE_IDS.add(PotionCache.templateId);
RIFT_CACHE.createTemplate();
CACHE_IDS.add(RiftCache.templateId);
TITAN_CACHE.createTemplate();
CACHE_IDS.add(TitanCache.templateId);
TOOL_CACHE.createTemplate();
//CACHE_IDS.add(ToolCache.templateId);
TREASUREMAP_CACHE.createTemplate();

View File

@@ -0,0 +1,93 @@
package mod.sin.wyvern;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.players.Player;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.logging.Logger;
public class CombatChanges {
public static Logger logger = Logger.getLogger(CombatChanges.class.getName());
public static float combatRatingAdditive(float combatRating, Creature cret, Creature opponent){
//logger.info("Checking additive ("+cret.getName()+" vs "+opponent.getName()+"), combatRating = "+combatRating);
float add = 0.0f;
if((cret != null && !cret.isPlayer()) || (opponent != null && !opponent.isPlayer())){
if(cret.isRoyalExecutioner()){
add += 2.0f;
}
}
return add;
}
public static float combatRatingMultiplicative(float combatRating, Creature cret, Creature opponent){
//logger.info("Checking mult ("+cret.getName()+" vs "+opponent.getName()+"), combatRating = "+combatRating);
float mult = 1.0f;
if(cret != null && cret.isDominated()){
//logger.info("Cret is a pet.");
if(cret.getDominator() != null) {
if (cret.getDominator() instanceof Player) {
Player owner = (Player) cret.getDominator();
double depth = owner.getSoulDepth().getKnowledge();
//logger.info("Multiplying combat rating by "+(depth*0.02d)+" due to owner Soul Depth.");
mult *= depth * 0.02d;
} else {
logger.info("Somehow a pet is dominated by a non-player? (" + cret.getDominator().getName() + ")");
}
}
}
return mult;
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<CombatChanges> thisClass = CombatChanges.class;
String replace;
Util.setReason("Make custom combat rating changes.");
CtClass ctCombatHandler = classPool.get("com.wurmonline.server.creatures.CombatHandler");
replace = "combatRating += "+CombatChanges.class.getName()+".combatRatingAdditive(combatRating, this.creature, $1);" +
"crmod *= "+CombatChanges.class.getName()+".combatRatingMultiplicative(combatRating, this.creature, $1);" +
"$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "getCombatRating", "getFlankingModifier", replace);
Util.setReason("Increase unique damage to pets.");
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);
replace = "if($2.isDominated() && $1 != null && $1.isUnique()){" +
//" logger.info(\"Detected unique hit on a pet. Adding damage.\");" +
" $5 = $5 * 2d;" +
"}";
Util.insertBeforeDescribed(thisClass, ctCombatEngine, "addWound", desc1, replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -28,7 +28,8 @@ public class Crystals {
Enchants.BUFF_VENOM,
Enchants.BUFF_WEBARMOUR,
Enchants.BUFF_WIND_OF_AGES,
110, 111 // Harden and Phasing
110 // Harden
//110, 111 // Harden and Phasing
};
public static byte getNewRandomEnchant(Item target){
int i = 0;
@@ -42,22 +43,16 @@ public class Crystals {
return -10;
}
public static double getInfusionDifficulty(Creature performer, Item source, Item target){
double diff = (Servers.localServer.PVPSERVER ? 150 : 120)-source.getCurrentQualityLevel();
diff += source.getRarity()*(Servers.localServer.PVPSERVER ? 50 : 30);
double diff = 100-source.getCurrentQualityLevel();
diff += source.getRarity()*20;
diff += 40f - (target.getCurrentQualityLevel()*0.4f);
diff -= performer.getSoulDepth().getKnowledge();
if(Servers.localServer.PVPSERVER){ // Added difficulty to account for PvP epic curve:
diff *= 1.4f;
}
diff -= performer.getMindLogical().getKnowledge()*0.3f;
return diff;
}
public static double getEnchantersInfusionDifficulty(Creature performer, Item source, Item target){
double diff = (Servers.localServer.PVPSERVER ? 220 : 180)-source.getCurrentQualityLevel();
double diff = 160-source.getCurrentQualityLevel();
diff += 40f - (target.getCurrentQualityLevel()*0.4f);
diff -= performer.getSoulDepth().getKnowledge();
if(Servers.localServer.PVPSERVER){ // Added difficulty to account for PvP epic curve:
diff *= 1.4f;
}
diff -= performer.getMindLogical().getKnowledge()*0.3f;
return diff;
}
public static boolean shouldCancelEnchantersInfusion(Creature performer, Item target){

View File

@@ -0,0 +1,79 @@
package mod.sin.wyvern;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.villages.GuardPlan;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import mod.sin.items.SealedMap;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.logging.Logger;
public class EconomicChanges {
public static Logger logger = Logger.getLogger(EconomicChanges.class.getName());
public static int getNewVillageTiles(int tiles){
float power = 2f;
float changeRate = 1000;
float maxNumTiles = 50000;
// =(C2) * (1-POW(C2/$C$16, $A$24)) + (SQRT(C2)*$A$26) * POW(C2/$C$16, $A$24)
return (int) ((float) tiles * (1-Math.pow((float) tiles /maxNumTiles, power)) + (Math.sqrt((float) tiles)*changeRate) * Math.pow((float) tiles /maxNumTiles, power));
}
// Used for full refunds of deeds minus guards.
public static long getNewDisbandMoney(GuardPlan gp, Village v){
int tiles = v.getDiameterX() * v.getDiameterY();
long tileCost = (long)tiles * Villages.TILE_COST;
long perimeterCost = v.getPerimeterSize() * Villages.PERIMETER_COST;
return gp.moneyLeft + tileCost + perimeterCost;
}
private static final float PRICE_MARKUP = 1f/1.4f;
public static int getNewValue(Item item){
if(item.getTemplateId() == SealedMap.templateId){
float qual = item.getQualityLevel();
float dam = item.getDamage();
// =($A$25*A2*A2 / 10000)
float initialValue = ((float)item.getTemplate().getValue())*qual*qual/10000f;
float baseCost = 100000f;
float power = 6.0f;
// =((10+B2/4.5)*(1-POW(A2/100, $A$27)) + B2*POW(A2/100, $A$27)) * ((100 - $A$29) / 100)
return (int) (((baseCost+(initialValue/4.5f)) * (1f-Math.pow(qual/100f, power)) + initialValue*Math.pow(qual/100f, power)) * ((100f-dam)/100f) * PRICE_MARKUP);
}
return -10;
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<EconomicChanges> thisClass = EconomicChanges.class;
String replace;
Util.setReason("Increase deed upkeep by modifying the amount of tiles it thinks it has.");
CtClass ctGuardPlan = classPool.get("com.wurmonline.server.villages.GuardPlan");
replace = "$_ = "+EconomicChanges.class.getName()+".getNewVillageTiles(vill.getNumTiles());";
Util.instrumentDeclared(thisClass, ctGuardPlan, "getMonthlyCost", "getNumTiles", replace);
/*Util.setReason("Allow players to get a full deed refund.");
replace = "{ return "+EconomicChanges.class.getName()+".getNewDisbandMoney(this, this.getVillage()); }";
Util.setBodyDeclared(thisClass, ctGuardPlan, "getDisbandMoneyLeft", replace);*/
Util.setReason("Adjust value for certain items.");
CtClass ctItem = classPool.get("com.wurmonline.server.items.Item");
replace = "int newVal = "+EconomicChanges.class.getName()+".getNewValue(this);"
+ "if(newVal > 0){"
+ " return newVal;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctItem, "getValue", replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import com.wurmonline.server.Servers;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modloader.classhooks.InvocationHandlerFactory;
@@ -41,6 +42,7 @@ public class ItemMod {
public static ArrowPackHunting ARROW_PACK_HUNTING = new ArrowPackHunting();
public static ArrowPackWar ARROW_PACK_WAR = new ArrowPackWar();
public static BattleYoyo BATTLE_YOYO = new BattleYoyo();
public static BookOfConversion BOOK_OF_CONVERSION = new BookOfConversion();
public static Club CLUB = new Club();
public static CoinDecoration COIN_DECORATION = new CoinDecoration();
public static CorpseDecoration CORPSE_DECORATION = new CorpseDecoration();
@@ -62,6 +64,10 @@ public class ItemMod {
public static Warhammer WARHAMMER = new Warhammer();
public static WarhammerHead WARHAMMER_HEAD = new WarhammerHead();
// Arena Fragments
public static KeyFragment KEY_FRAGMENT = new KeyFragment();
public static SorceryFragment SORCERY_FRAGMENT = new SorceryFragment();
// Crystals
public static ChaosCrystal CHAOS_CRYSTAL = new ChaosCrystal();
public static EnchantersCrystal ENCHANTERS_CRYSTAL = new EnchantersCrystal();
@@ -99,6 +105,7 @@ public class ItemMod {
ARROW_PACK_HUNTING.createTemplate();
ARROW_PACK_WAR.createTemplate();
BATTLE_YOYO.createTemplate();
BOOK_OF_CONVERSION.createTemplate();
CLUB.createTemplate();
COIN_DECORATION.createTemplate();
CORPSE_DECORATION.createTemplate();
@@ -120,6 +127,10 @@ public class ItemMod {
WARHAMMER.createTemplate();
WARHAMMER_HEAD.createTemplate();
// Arena Fragments
KEY_FRAGMENT.createTemplate();
SORCERY_FRAGMENT.createTemplate();
// Crystals
CHAOS_CRYSTAL.createTemplate();
ENCHANTERS_CRYSTAL.createTemplate();
@@ -156,6 +167,7 @@ public class ItemMod {
ModActions.registerAction(new AffinityOrbAction());
ModActions.registerAction(new ArenaCacheOpenAction());
ModActions.registerAction(new ArrowPackUnpackAction());
ModActions.registerAction(new BookConversionAction());
ModActions.registerAction(new CrystalCombineAction());
ModActions.registerAction(new ChaosCrystalInfuseAction());
ModActions.registerAction(new DepthDrillAction());
@@ -174,21 +186,21 @@ public class ItemMod {
ARROW_PACK_WAR.initCreationEntry();
BATTLE_YOYO.initCreationEntry();
CLUB.initCreationEntry();
COIN_DECORATION.initCreationEntry();
CORPSE_DECORATION.initCreationEntry();
//COIN_DECORATION.initCreationEntry();
//CORPSE_DECORATION.initCreationEntry();
DEPTH_DRILL.initCreationEntry();
EVISCERATOR.initCreationEntry();
KNUCKLES.initCreationEntry();
MASS_STORAGE_UNIT.initCreationEntry();
SKELETON_DECORATION.initCreationEntry();
//SKELETON_DECORATION.initCreationEntry();
SOUL_FORGE.initCreationEntry();
STATUETTE_BREYK.initCreationEntry();
STATUETTE_CYBERHUSKY.initCreationEntry();
//STATUETTE_BREYK.initCreationEntry();
//STATUETTE_CYBERHUSKY.initCreationEntry();
WARHAMMER.initCreationEntry();
WARHAMMER_HEAD.initCreationEntry();
// Spectral set
SPECTRAL_BOOT.initCreationEntry();
/*SPECTRAL_BOOT.initCreationEntry();
SPECTRAL_CAP.initCreationEntry();
SPECTRAL_GLOVE.initCreationEntry();
SPECTRAL_HOSE.initCreationEntry();
@@ -202,7 +214,7 @@ public class ItemMod {
GLIMMERSCALE_HELMET.initCreationEntry();
GLIMMERSCALE_HOSE.initCreationEntry();
GLIMMERSCALE_SLEEVE.initCreationEntry();
GLIMMERSCALE_VEST.initCreationEntry();
GLIMMERSCALE_VEST.initCreationEntry();*/
// Allow sickle heads from steel & moon metals:
// [3/28/18] Disabled: Implemented in WU 1.6.
@@ -251,17 +263,17 @@ public class ItemMod {
public static void createCustomWeapons(){
try {
logger.info("Beginning custom weapon creation.");
new Weapon(BattleYoyo.templateId, 7.75f, 3.5f, 0.008f, 2, 2, 0.0f, 0d);
new Weapon(Club.templateId, 8.5f, 4.1f, 0.002f, 3, 3, 0.4f, 0.5d);
new Weapon(Knuckles.templateId, 4.1f, 1f, 0.002f, 1, 1, 0.2f, 0.5d);
new Weapon(Warhammer.templateId, 9.75f, 5.2f, 0.008f, 4, 3, 1f, 0d);
new Weapon(BattleYoyo.templateId, 6.85f, 3.85f, 0.008f, 2, 2, 0.0f, 0d);
new Weapon(Club.templateId, 8.1f, 4.5f, 0.002f, 3, 3, 0.4f, 0.5d);
new Weapon(Knuckles.templateId, 3.6f, 2.2f, 0.002f, 1, 1, 0.2f, 0.5d);
new Weapon(Warhammer.templateId, 9.55f, 5.5f, 0.008f, 4, 3, 1f, 0d);
// Titan weaponry
new Weapon(MaartensMight.templateId, 11, 5, 0.02f, 4, 4, 1.0f, 0d);
new Weapon(RaffehsRage.templateId, 9.5f, 4.25f, 0.02f, 3, 3, 1.0f, 0d);
new Weapon(VindictivesVengeance.templateId, 9, 4f, 0.02f, 3, 3, 0.5f, 0d);
new Weapon(WilhelmsWrath.templateId, 6f, 4.5f, 0.02f, 6, 6, 0.5f, 0d);
// Genocide weapon
new Weapon(Eviscerator.templateId, 11, 4.5f, 0.02f, 5, 5, 0.4f, 0.5d);
new Weapon(Eviscerator.templateId, 100, 3f, 0.02f, 5, 5, 0.4f, 0.5d);
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
@@ -301,22 +313,23 @@ public class ItemMod {
ItemTemplate leather = ItemTemplateFactory.getInstance().getTemplate(ItemList.leather);
ReflectionUtil.setPrivateField(leather, ReflectionUtil.getField(leather.getClass(), "combine"), true);
// Make logs able to be combined.
ItemTemplate log = ItemTemplateFactory.getInstance().getTemplate(ItemList.log);
ReflectionUtil.setPrivateField(log, ReflectionUtil.getField(log.getClass(), "combine"), true);
// Set silver mirror price to 10 silver instead of 1 iron.
ItemTemplate handMirror = ItemTemplateFactory.getInstance().getTemplate(ItemList.handMirror);
ReflectionUtil.setPrivateField(handMirror, ReflectionUtil.getField(handMirror.getClass(), "value"), 500000);
ReflectionUtil.setPrivateField(handMirror, ReflectionUtil.getField(handMirror.getClass(), "value"), 200000);
ItemTemplate goldMirror = ItemTemplateFactory.getInstance().getTemplate(ItemList.goldenMirror);
ReflectionUtil.setPrivateField(goldMirror, ReflectionUtil.getField(goldMirror.getClass(), "value"), 3000000);
ReflectionUtil.setPrivateField(goldMirror, ReflectionUtil.getField(goldMirror.getClass(), "value"), 1000000);
// Set transmutation rod to 2 gold instead of 50 silver.
//ItemTemplate transmutationRod = ItemTemplateFactory.getInstance().getTemplate(668);
//ReflectionUtil.setPrivateField(transmutationRod, ReflectionUtil.getField(transmutationRod.getClass(), "value"), 2000000);
// Make logs able to be combined.
ItemTemplate log = ItemTemplateFactory.getInstance().getTemplate(ItemList.log);
ReflectionUtil.setPrivateField(log, ReflectionUtil.getField(log.getClass(), "combine"), true);
// " return this.isTransportable || (this.getTemplateId() >= 510 && this.getTemplateId() <= 513) || this.getTemplateId() == 722 || this.getTemplateId() == 670;"
// Make mailboxes loadable
// Make mailboxes loadable (PvE Only)
if(!Servers.localServer.PVPSERVER) {
ItemTemplate mailboxWood = ItemTemplateFactory.getInstance().getTemplate(ItemList.mailboxWood);
ReflectionUtil.setPrivateField(mailboxWood, ReflectionUtil.getField(mailboxWood.getClass(), "isTransportable"), true);
ItemTemplate mailboxStone = ItemTemplateFactory.getInstance().getTemplate(ItemList.mailboxStone);
@@ -325,6 +338,7 @@ public class ItemMod {
ReflectionUtil.setPrivateField(mailboxWood2, ReflectionUtil.getField(mailboxWood2.getClass(), "isTransportable"), true);
ItemTemplate mailboxStone2 = ItemTemplateFactory.getInstance().getTemplate(ItemList.mailboxStoneTwo);
ReflectionUtil.setPrivateField(mailboxStone2, ReflectionUtil.getField(mailboxStone2.getClass(), "isTransportable"), true);
}
// Make bell towers and trash bins loadable
ItemTemplate bellTower = ItemTemplateFactory.getInstance().getTemplate(ItemList.bellTower);
@@ -356,6 +370,14 @@ public class ItemMod {
ItemTemplate sandstone = ItemTemplateFactory.getInstance().getTemplate(ItemList.sandstone);
ReflectionUtil.setPrivateField(sandstone, ReflectionUtil.getField(sandstone.getClass(), "difficulty"), 50.0f);
// Make some useless items decorations for added interior design.
ItemTemplate stoneKeystone = ItemTemplateFactory.getInstance().getTemplate(ItemList.stoneKeystone);
ReflectionUtil.setPrivateField(stoneKeystone, ReflectionUtil.getField(stoneKeystone.getClass(), "decoration"), true);
ItemTemplate marbleKeystone = ItemTemplateFactory.getInstance().getTemplate(ItemList.marbleKeystone);
ReflectionUtil.setPrivateField(marbleKeystone, ReflectionUtil.getField(marbleKeystone.getClass(), "decoration"), true);
ItemTemplate skull = ItemTemplateFactory.getInstance().getTemplate(ItemList.skull);
ReflectionUtil.setPrivateField(skull, ReflectionUtil.getField(skull.getClass(), "decoration"), true);
createCustomWeapons();
createCustomArmours();

View File

@@ -0,0 +1,253 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.NoSuchPlayerException;
import com.wurmonline.server.Server;
import com.wurmonline.server.TimeConstants;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.MovementScheme;
import com.wurmonline.server.creatures.NoSuchCreatureException;
import com.wurmonline.server.creatures.SpellEffectsEnum;
import com.wurmonline.server.players.Cultist;
import com.wurmonline.server.players.Cults;
import com.wurmonline.server.players.Player;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.logging.Logger;
public class MeditationPerks {
public static Logger logger = Logger.getLogger(MeditationPerks.class.getName());
public static void sendPassiveBuffs(Cultist cultist){
byte path = cultist.getPath();
byte level = cultist.getLevel();
try {
Creature cret = Server.getInstance().getCreature(cultist.getWurmId());
if(path == Cults.PATH_HATE && level >= 4){
float levelDiff = level-3f;
cret.getCommunicator().sendAddSpellEffect(SpellEffectsEnum.DEITY_MOVEBONUS, -1, levelDiff);
}
if(path == Cults.PATH_INSANITY && level >= 7){
float levelDiff = level-6f;
cret.getCommunicator().sendAddSpellEffect(SpellEffectsEnum.INSANITY_SHIELD_GONE, -1, levelDiff*2f);
}
if(path == Cults.PATH_KNOWLEDGE && level >= 7){
float levelDiff = level-6f;
cret.getCommunicator().sendAddSpellEffect(SpellEffectsEnum.KNOWLEDGE_INCREASED_SKILL_GAIN, -1, levelDiff*5f);
}
if(path == Cults.PATH_POWER && level >= 7){
float levelDiff = level-6f;
cret.getCommunicator().sendAddSpellEffect(SpellEffectsEnum.POWER_USES_LESS_STAMINA, -1, levelDiff*5f);
}
} catch (NoSuchPlayerException | NoSuchCreatureException e) {
e.printStackTrace();
}
}
public static float getCultistSpeedMultiplier(MovementScheme scheme){
try {
Creature cret = ReflectionUtil.getPrivateField(scheme, ReflectionUtil.getField(scheme.getClass(), "creature"));
if(cret != null){
if(cret.getCultist() != null){
Cultist path = cret.getCultist();
if(path.getPath() == Cults.PATH_HATE){
byte level = path.getLevel();
if(level >= 3){
float levelDiff = level-3f;
return 1.0f+(levelDiff*0.01f);
}
}
}
}
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
return 1.0f;
}
public static float newStaminaModifierFor(Creature performer, int staminaNeeded){
int currstam = performer.getStatus().getStamina();
float staminaMod = 1.0f;
if (currstam > 60000) {
staminaMod = 0.8f;
}
if(performer.getCultist() != null){
Cultist path = performer.getCultist();
if(path.getPath() == Cults.PATH_INSANITY){
byte level = path.getLevel();
if(level >= 7){
float levelDiff = level-6f;
float insanityMod = 1.0f-(levelDiff*0.02f);
staminaMod *= insanityMod;
}
}
}
staminaMod += 1.0f - (float)currstam / 65535.0f;
if (currstam < staminaNeeded) {
float diff = staminaNeeded - currstam;
staminaMod += diff / (float)staminaNeeded * performer.getStaminaMod();
}
return staminaMod;
}
public static float getPowerStaminaBonus(Creature creature){
if(creature instanceof Player){
Player player = (Player) creature;
if(player.getCultist() != null){
Cultist path = player.getCultist();
if(path.getPath() == Cults.PATH_POWER){
byte level = path.getLevel();
if(level >= 7){
float levelDiff = level-6f;
return (levelDiff*0.05f);
}
}
}
}
return 0f;
}
public static float getKnowledgeSkillGain(Player player){
if(player.getCultist() != null){
Cultist path = player.getCultist();
if(path.getPath() == Cults.PATH_KNOWLEDGE){
byte level = path.getLevel();
if(level >= 7){
float levelDiff = level-6f;
return 1.0f+(levelDiff*0.05f);
}
}
}
return 1.0f;
}
public static byte getNewPathFor(int tilex, int tiley, int layer){
if (layer < 0) {
return Cults.PATH_INSANITY;
}
int tile = Server.surfaceMesh.getTile(tilex, tiley);
byte type = Tiles.decodeType(tile);
Tiles.Tile theTile = Tiles.getTile(type);
if (theTile.isGrass() || theTile.isBush() || theTile.isTree()){
return Cults.PATH_LOVE;
}
if (theTile.isMycelium() || theTile.isMyceliumBush() || theTile.isMyceliumTree()){
return Cults.PATH_HATE;
}
if (type == Tiles.TILE_TYPE_SAND){
return Cults.PATH_KNOWLEDGE;
}
if (type == Tiles.TILE_TYPE_ROCK || type == Tiles.TILE_TYPE_CLIFF){
return Cults.PATH_POWER;
}
return Cults.PATH_NONE;
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<MeditationPerks> thisClass = MeditationPerks.class;
String replace;
Util.setReason("Enable buff icons for meditation.");
CtClass ctCultist = classPool.get("com.wurmonline.server.players.Cultist");
replace = MeditationPerks.class.getName()+".sendPassiveBuffs($0);";
Util.insertBeforeDeclared(thisClass, ctCultist, "sendPassiveBuffs", replace);
Util.setReason("Make meditating paths more straightforward.");
CtClass ctCults = classPool.get("com.wurmonline.server.players.Cults");
replace = "{ return "+MeditationPerks.class.getName()+".getNewPathFor($1, $2, $3); }";
Util.setBodyDeclared(thisClass, ctCults, "getPathFor", replace);
Util.setReason("Replace stamina modifier for new Insanity ability.");
CtClass ctActions = classPool.get("com.wurmonline.server.behaviours.Actions");
replace = "{ return "+MeditationPerks.class.getName()+".newStaminaModifierFor($1, $2); }";
Util.setBodyDeclared(thisClass, ctActions, "getStaminaModiferFor", replace);
Util.setReason("Increase movement speed for Path of Hate users.");
CtClass ctMovementScheme = classPool.get("com.wurmonline.server.creatures.MovementScheme");
replace = "if($_ > 0){" +
" $_ = $_ * "+MeditationPerks.class.getName()+".getCultistSpeedMultiplier(this);" +
"}";
Util.insertAfterDeclared(thisClass, ctMovementScheme, "getSpeedModifier", replace);
Util.setReason("Scale path of power stamina bonus from level 7 onwards.");
CtClass ctCreatureStatus = classPool.get("com.wurmonline.server.creatures.CreatureStatus");
replace = "staminaMod += "+MeditationPerks.class.getName()+".getPowerStaminaBonus(this.statusHolder);" +
"$_ = false;";
Util.instrumentDeclared(thisClass, ctCreatureStatus, "modifyStamina", "usesNoStamina", replace);
Util.setReason("Scale path of knowledge skill gain from level 7 onwards.");
CtClass ctSkill = classPool.get("com.wurmonline.server.skills.Skill");
CtClass[] params1 = {
CtClass.doubleType,
CtClass.booleanType,
CtClass.floatType,
CtClass.booleanType,
CtClass.doubleType
};
String desc1 = Descriptor.ofMethod(CtClass.voidType, params1);
replace = "staminaMod *= "+MeditationPerks.class.getName()+".getKnowledgeSkillGain(player);" +
"$_ = false;";
Util.instrumentDescribed(thisClass, ctSkill, "alterSkill", desc1, "levelElevenSkillgain", replace);
Util.setReason("Remove shield of the gone effect.");
replace = "{ return 0.0f; }";
Util.setBodyDeclared(thisClass, ctCultist, "getHalfDamagePercentage", replace);
Util.setReason("Remove hate war damage effect.");
replace = "{ return false; }";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartDoubleWarDamage", replace);
Util.setBodyDeclared(thisClass, ctCultist, "doubleWarDamage", replace);
Util.setReason("Remove artifical tick timer for meditation.");
replace = "$_ = 0;";
Util.instrumentDeclared(thisClass, ctCults, "meditate", "getLastMeditated", replace);
// - Reduce meditation cooldowns - //
replace = "return this.path == 1 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayRefresh", replace);
//ctCultist.getDeclaredMethod("mayRefresh").setBody("return this.path == 1 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > 28800000;");
replace = "return this.path == 1 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayEnchantNature", replace);
//ctCultist.getDeclaredMethod("mayEnchantNature").setBody("return this.path == 1 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 28800000;");
replace = "return this.path == 1 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartLoveEffect", replace);
//ctCultist.getDeclaredMethod("mayStartLoveEffect").setBody("return this.path == 1 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > 14400000;");
replace = "return this.path == 2 && this.level > 6 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartDoubleWarDamage", replace);
//ctCultist.getDeclaredMethod("mayStartDoubleWarDamage").setBody("return this.path == 2 && this.level > 6 && System.currentTimeMillis() - this.cooldown1 > 21600000;");
replace = "return this.path == 2 && this.level > 3 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartDoubleStructDamage", replace);
//ctCultist.getDeclaredMethod("mayStartDoubleStructDamage").setBody("return this.path == 2 && this.level > 3 && System.currentTimeMillis() - this.cooldown2 > 14400000;");
replace = "return this.path == 2 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartFearEffect", replace);
//ctCultist.getDeclaredMethod("mayStartFearEffect").setBody("return this.path == 2 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > 21600000;");
replace = "return this.path == 5 && this.level > 8 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartNoElementalDamage", replace);
//ctCultist.getDeclaredMethod("mayStartNoElementalDamage").setBody("return this.path == 5 && this.level > 8 && System.currentTimeMillis() - this.cooldown1 > 21600000;");
replace = "return this.path == 5 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "maySpawnVolcano", replace);
//ctCultist.getDeclaredMethod("maySpawnVolcano").setBody("return this.path == 5 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 28800000;");
replace = "return this.path == 5 && this.level > 3 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartIgnoreTraps", replace);
//ctCultist.getDeclaredMethod("mayStartIgnoreTraps").setBody("return this.path == 5 && this.level > 3 && System.currentTimeMillis() - this.cooldown3 > 14400000;");
replace = "return this.path == 3 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayCreatureInfo", replace);
//ctCultist.getDeclaredMethod("mayCreatureInfo").setBody("return this.path == 3 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > 14400000;");
replace = "return this.path == 3 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayInfoLocal", replace);
//ctCultist.getDeclaredMethod("mayInfoLocal").setBody("return this.path == 3 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 14400000;");
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -1,18 +1,15 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.*;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.creatures.*;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.modifiers.DoubleValueModifier;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.skills.NoSuchSkillException;
import com.wurmonline.server.skills.Skill;
import com.wurmonline.server.players.PlayerInfo;
import com.wurmonline.server.players.PlayerInfoFactory;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.webinterface.WcKingdomChat;
import com.wurmonline.server.zones.NoSuchZoneException;
import com.wurmonline.server.zones.Zone;
import com.wurmonline.server.zones.VolaTile;
import com.wurmonline.server.zones.Zones;
import com.wurmonline.shared.constants.Enchants;
import javassist.*;
@@ -20,220 +17,21 @@ import javassist.bytecode.Descriptor;
import javassist.expr.ExprEditor;
import javassist.expr.FieldAccess;
import javassist.expr.MethodCall;
import mod.sin.creatures.*;
import mod.sin.items.SealedMap;
import mod.sin.lib.Util;
import mod.sin.wyvern.arena.Arena;
import mod.sin.wyvern.bestiary.MethodsBestiary;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import org.nyxcode.wurm.discordrelay.DiscordRelay;
import java.util.HashMap;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MiscChanges {
public static Logger logger = Logger.getLogger(MiscChanges.class.getName());
public static byte newCreatureType(int templateid, byte ctype) throws Exception{
CreatureTemplate template = CreatureTemplateFactory.getInstance().getTemplate(templateid);
if(ctype == 0 && (template.isAggHuman() || template.getBaseCombatRating() > 10) && !template.isUnique() && !Arena.isTitan(templateid)){
if(Server.rand.nextInt(5) == 0){
ctype = (byte) (Server.rand.nextInt(11)+1);
if(Server.rand.nextInt(50) == 0){
ctype = 99;
}
}
}
return ctype;
}
protected static HashMap<Creature, Double> defDamage = new HashMap<>();
public static void setDefDamage(Creature cret, double damage){
defDamage.put(cret, damage);
}
public static double getDefDamage(Creature cret){
if(defDamage.containsKey(cret)){
double theDamage = defDamage.get(cret);
defDamage.remove(cret);
return theDamage;
}
logger.severe("Severe error: could not find defDamage for creature "+cret);
return 0d;
}
public static int getNewVillageTiles(int tiles){
float power = 2f;
float changeRate = 1000;
float maxNumTiles = 50000;
// =(C2) * (1-POW(C2/$C$16, $A$24)) + (SQRT(C2)*$A$26) * POW(C2/$C$16, $A$24)
return (int) ((float) tiles * (1-Math.pow((float) tiles /maxNumTiles, power)) + (Math.sqrt((float) tiles)*changeRate) * Math.pow((float) tiles /maxNumTiles, power));
}
private static final float PRICE_MARKUP = 1f/1.4f;
public static int getNewValue(Item item){
if(item.getTemplateId() == SealedMap.templateId){
float qual = item.getQualityLevel();
float dam = item.getDamage();
// =($A$25*A2*A2 / 10000)
float initialValue = ((float)item.getTemplate().getValue())*qual*qual/10000f;
float baseCost = 100000f;
float power = 11.0f;
// =((10+B2/4.5)*(1-POW(A2/100, $A$27)) + B2*POW(A2/100, $A$27)) * ((100 - $A$29) / 100)
return (int) (((baseCost+(initialValue/4.5f)) * (1f-Math.pow(qual/100f, power)) + initialValue*Math.pow(qual/100f, power)) * ((100f-dam)/100f) * PRICE_MARKUP);
}
return -10;
}
public static void checkEnchantedBreed(Creature creature){
int tile = Server.surfaceMesh.getTile(creature.getTileX(), creature.getTileY());
byte type = Tiles.decodeType(tile);
if (type == Tiles.Tile.TILE_ENCHANTED_GRASS.id){
logger.info("Creature "+creature.getName()+" was born on enchanted grass, and has a negative trait removed!");
Server.getInstance().broadCastAction(creature.getName()+" was born on enchanted grass, and feels more healthy!", creature, 10);
creature.removeRandomNegativeTrait();
}
}
public static boolean hasCustomCorpseSize(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == Avenger.templateId){
return true;
}else{
return Arena.isTitan(creature);
}
}
public static boolean insertItemIntoVehicle(Item item, Item vehicle, Creature performer) {
// If can put into crates, try that
if (item.getTemplate().isBulk() && item.getRarity() == 0) {
for (Item container : vehicle.getAllItems(true)) {
if(container.getTemplateId() == ItemList.bulkContainer){
if(container.getFreeVolume() >= item.getVolume()){
if (item.AddBulkItem(performer, container)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s in your %s.", item.getName(), container.getName(), vehicle.getName()));
return true;
}
}
}
if (container.isCrate() && container.canAddToCrate(item)) {
if (item.AddBulkItemToCrate(performer, container)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s in your %s.", item.getName(), container.getName(), vehicle.getName()));
return true;
}
}
}
}
// No empty crates or disabled, try the vehicle itself
if (vehicle.getNumItemsNotCoins() < 100 && vehicle.getFreeVolume() >= item.getVolume() && vehicle.insertItem(item)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s.", item.getName(), vehicle.getName()));
return true;
} else {
// Send message if the vehicle is too full
performer.getCommunicator().sendNormalServerMessage(String.format("The %s is too full to hold the %s.", vehicle.getName(), item.getName()));
return false;
}
}
public static Item getVehicleSafe(Creature pilot) {
try {
if (pilot.getVehicle() != -10)
return Items.getItem(pilot.getVehicle());
} catch (NoSuchItemException ignored) {
}
return null;
}
public static void miningHook(Creature performer, Item ore){
Item vehicleItem = getVehicleSafe(performer);
if(vehicleItem != null && vehicleItem.isHollow()){
if(insertItemIntoVehicle(ore, vehicleItem, performer)){
return;
}
}
// Last resort, if no suitable vehicle is found.
try {
ore.putItemInfrontof(performer);
} catch (NoSuchCreatureException | NoSuchItemException | NoSuchPlayerException | NoSuchZoneException e) {
e.printStackTrace();
}
}
public static void setCorpseSizes(Creature creature, Item corpse){
if(corpse.getTemplateId() != ItemList.corpse){
return;
}
int templateId = creature.getTemplate().getTemplateId();
boolean sendStatus = false;
int size = 50000;
if(templateId == Avenger.templateId){
size *= 1.2;
corpse.setSizes(size);
sendStatus = true;
}else if(Arena.isTitan(creature)){
size *= 1.5;
corpse.setSizes(size);
sendStatus = true;
}else{
corpse.setSizes((int)((float)(corpse.getSizeX() * (creature.getSizeModX() & 255)) / 64.0f), (int)((float)(corpse.getSizeY() * (creature.getSizeModY() & 255)) / 64.0f), (int)((float)(corpse.getSizeZ() * (creature.getSizeModZ() & 255)) / 64.0f));
}
if(sendStatus){
try {
Zone zone = Zones.getZone((int)corpse.getPosX() >> 2, (int)corpse.getPosY() >> 2, corpse.isOnSurface());
zone.removeItem(corpse, true, true);
zone.addItem(corpse, true, false, false);
} catch (NoSuchZoneException e) {
e.printStackTrace();
}
}
}
public static void setNewMoveLimits(Creature cret){
try {
Skill strength = cret.getSkills().getSkill(102);
ReflectionUtil.setPrivateField(cret, ReflectionUtil.getField(cret.getClass(), "moveslow"), strength.getKnowledge()*4000);
ReflectionUtil.setPrivateField(cret, ReflectionUtil.getField(cret.getClass(), "encumbered"), strength.getKnowledge()*7000);
ReflectionUtil.setPrivateField(cret, ReflectionUtil.getField(cret.getClass(), "cantmove"), strength.getKnowledge()*14000);
MovementScheme moveScheme = cret.getMovementScheme();
DoubleValueModifier stealthMod = ReflectionUtil.getPrivateField(moveScheme, ReflectionUtil.getField(moveScheme.getClass(), "stealthMod"));
if (stealthMod == null) {
stealthMod = new DoubleValueModifier((- 80.0 - Math.min(79.0, cret.getBodyControl())) / 100.0);
} else {
stealthMod.setModifier((- 80.0 - Math.min(79.0, cret.getBodyControl())) / 100.0);
}
ReflectionUtil.setPrivateField(moveScheme, ReflectionUtil.getField(moveScheme.getClass(), "stealthMod"), stealthMod);
}
catch (NoSuchSkillException | IllegalArgumentException | IllegalAccessException | ClassCastException | NoSuchFieldException nss) {
logger.log(Level.WARNING, "No strength skill for " + cret, nss);
}
}
public static boolean shouldBreedName(Creature creature){
if(creature.getTemplate().getTemplateId() == WyvernBlack.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernGreen.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernRed.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernWhite.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == Charger.templateId){
return true;
}
return creature.isHorse();
}
public static boolean isGhostCorpse(Creature creature){
if(creature.getTemplate().getTemplateId() == Avenger.templateId){
return true;
}else{
return creature.getTemplate().getTemplateId() == SpiritTroll.templateId;
}
}
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) {
@@ -252,8 +50,9 @@ public class MiscChanges {
return -1;
}
public static void sendServerTabMessage(final String message, final int red, final int green, final int blue){
DiscordRelay.sendToDiscord("event", message);
public static void sendServerTabMessage(String channel, final String message, final int red, final int green, final int blue){
DiscordRelay.sendToDiscord(channel, message, true);
// WARNING: Never change this from a new Runnable. Lambdas are a lie and will break everything.
Runnable r = new Runnable() {
public void run() {
Message mess;
@@ -284,14 +83,66 @@ public class MiscChanges {
};
r.run();
}
public static void sendImportantMessage(Creature sender, String message, int red, int green, int blue){
sendServerTabMessage("<"+sender.getNameWithoutPrefixes()+"> "+message, red, green, blue);
sendGlobalFreedomChat(sender, message, red, green, blue);
}
public static void broadCastDeaths(Creature player, String slayers){
sendGlobalFreedomChat(player, "slain by "+slayers, 200, 25, 25);
DiscordRelay.sendToDiscord("deaths", player+" slain by "+slayers);
String slayMessage = "slain by ";
sendGlobalFreedomChat(player, slayMessage+slayers, 200, 25, 25);
addPlayerStatsDeath(player.getName());
addPlayerStatsKill(slayers);
DiscordRelay.sendToDiscord("deaths", player.getName()+" "+slayMessage+slayers, true);
}
public static void addPlayerStatsDeath(String playerName){
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("UPDATE PlayerStats SET DEATHS = DEATHS + 1 WHERE NAME = \""+playerName+"\"");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void addPlayerStatsKill(String slayers){
String[] slayerNames = slayers.split(" ");
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
for(String slayer : slayerNames) {
if(slayer.length() < 2) continue;
ps = dbcon.prepareStatement("UPDATE PlayerStats SET KILLS = KILLS + 1 WHERE NAME = \"" + slayer + "\"");
ps.executeUpdate();
ps.close();
}
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static boolean checkMayorCommand(Item item, Creature creature){
if(Servers.localServer.PVPSERVER){
return false;
}
PlayerInfo pinf = PlayerInfoFactory.getPlayerInfoWithWurmId(item.getLastOwnerId());
if(pinf != null){
if(pinf.getLastLogout() < System.currentTimeMillis()-TimeConstants.DAY_MILLIS*7){
if(creature.getCitizenVillage() != null){
Village v = creature.getCitizenVillage();
if(v.getMayor().getId() == creature.getWurmId()){
VolaTile vt = Zones.getTileOrNull(item.getTilePos(), item.isOnSurface());
if(vt != null && vt.getVillage() != null && vt.getVillage() == v){
return true;
}
}
}
}
}
return false;
}
public static void preInit(){
@@ -307,7 +158,7 @@ public class MiscChanges {
// Initial messages:
String[] infoTabLine = {"Server Thread: https://forum.wurmonline.com/index.php?/topic/162067-revenant-modded-pvepvp-3x-action-new-skillgain/",
"Server Discord: https://discord.gg/r8QNXAC",
"Server Maps: Coming Soon..."};
"Server Maps: https://www.sarcasuals.com/revenant/"};
StringBuilder str = new StringBuilder("{"
+ " com.wurmonline.server.Message mess;");
for (String anInfoTabLine : infoTabLine) {
@@ -332,26 +183,10 @@ public class MiscChanges {
+ " }"
+ "}";
Util.instrumentDeclared(thisClass, ctItem, "moveToItem", "getOwnerId", replace);
/*ctItem.getDeclaredMethod("moveToItem").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getOwnerId")) {
m.replace("$_ = $proceed($$);"
+ "com.wurmonline.server.items.Item theTarget = com.wurmonline.server.Items.getItem(targetId);"
+ "if(theTarget != null && theTarget.getTemplateId() >= 510 && theTarget.getTemplateId() <= 513){"
+ " if(theTarget.getTopParent() != theTarget.getWurmId()){"
+ " mover.getCommunicator().sendNormalServerMessage(\"Mailboxes cannot be used while loaded.\");"
+ " return false;"
+ " }"
+ "}");
return;
}
}
});*/
// - Enable creature custom colors - (Used for creating custom color creatures eg. Lilith) - //
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
Util.setBodyDeclared(thisClass, ctCreature, "hasCustomColor", "{ return true; }");
//ctCreature.getDeclaredMethod("hasCustomColor").setBody("{ return true; }");
// - Increase the amount of checks for new unique spawns by 5x - //
CtClass ctServer = classPool.get("com.wurmonline.server.Server");
@@ -359,47 +194,20 @@ public class MiscChanges {
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctServer, "run", "checkDens", replace);
/*ctServer.getDeclaredMethod("run").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("checkDens")) {
m.replace("for(int i = 0; i < 5; i++){$_ = $proceed($$);}");
return;
}
}
});*/
// - Change rarity odds when a player obtains a rarity window - //
// [3/27] Removed: Merged to ServerTweaks
/*CtClass ctPlayer = classPool.get("com.wurmonline.server.players.Player");
replace = "{ return "+MiscChanges.class.getName()+".newGetPlayerRarity(this); }";
Util.setBodyDeclared(thisClass, ctPlayer, "getRarity", replace);*/
//ctPlayer.getDeclaredMethod("getRarity").setBody("{ return mod.sin.wyvern.MiscChanges.newGetPlayerRarity(this); }");
// - Add Facebreyker to the list of spawnable uniques - //
// TODO: Re-enable after Facebreyker initialized.
/*CtClass ctDens = classPool.get("com.wurmonline.server.zones.Dens");
CtClass ctDens = classPool.get("com.wurmonline.server.zones.Dens");
replace = "com.wurmonline.server.zones.Dens.checkTemplate(2147483643, whileRunning);";
Util.insertBeforeDeclared(thisClass, ctDens, "checkDens", replace);*/
Util.insertBeforeDeclared(thisClass, ctDens, "checkDens", replace);
//ctDens.getDeclaredMethod("checkDens").insertAt(0, "com.wurmonline.server.zones.Dens.checkTemplate(2147483643, whileRunning);");
// - Announce player titles in the Server tab - //
CtClass ctPlayer = classPool.get("com.wurmonline.server.players.Player");
replace = "$_ = $proceed($$);"
+ "if(!com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " "+MiscChanges.class.getName()+".sendServerTabMessage(this.getName()+\" just earned the title of \"+title.getName(this.isNotFemale())+\"!\", 200, 100, 0);"
+ "if(!com.wurmonline.server.Servers.localServer.PVPSERVER && this.getPower() < 1){"
+ " "+MiscChanges.class.getName()+".sendServerTabMessage(\"event\", this.getName()+\" just earned the title of \"+title.getName(this.isNotFemale())+\"!\", 200, 100, 0);"
+ "}";
Util.instrumentDeclared(thisClass, ctPlayer, "addTitle", "sendNormalServerMessage", replace);
/*ctPlayer.getDeclaredMethod("addTitle").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("sendNormalServerMessage")) {
m.replace("$_ = $proceed($$);"
+ "if(!com.wurmonline.server.Servers.localServer.PVPSERVER){"
+ " mod.sin.wyvern.MiscChanges.sendServerTabMessage(this.getName()+\" just earned the title of \"+title.getName(this.isNotFemale())+\"!\", 200, 100, 0);"
+ "}");
return;
}
}
});*/
// - Make leather not suck even after it's able to be combined. - //
CtClass ctMethodsItems = classPool.get("com.wurmonline.server.behaviours.MethodsItems");
@@ -409,65 +217,14 @@ public class MiscChanges {
+ " $_ = false;"
+ "}";
Util.instrumentDeclared(thisClass, ctMethodsItems, "improveItem", "isCombine", replace);
/*ctMethodsItems.getDeclaredMethod("improveItem").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isCombine")) {
m.replace("if(com.wurmonline.server.behaviours.MethodsItems.getImproveTemplateId(target) != 72){"
+ " $_ = $proceed($$);"
+ "}else{"
+ " $_ = false;"
+ "}");
return;
}
}
});*/
// - Check new improve materials - //
replace = "int temp = "+ItemMod.class.getName()+".getModdedImproveTemplateId($1);"
// TODO: Re-enable when custom items are created that require it.
/*replace = "int temp = "+ItemMod.class.getName()+".getModdedImproveTemplateId($1);"
+ "if(temp != -10){"
+ " return temp;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctMethodsItems, "getImproveTemplateId", replace);
/*ctMethodsItems.getDeclaredMethod("getImproveTemplateId").insertBefore(""
+ "int temp = mod.sin.wyvern.ItemMod.getModdedImproveTemplateId($1);"
+ "if(temp != -10){"
+ " return temp;"
+ "}");*/
// - Removal of eye/face shots to headshots instead - //
// [4/2/18] Removed: Unnecessary - WU 1.6 update resolves the reason it was done.
/*HookManager.getInstance().registerHook("com.wurmonline.server.combat.Armour", "getArmourPosForPos", "(I)I", new InvocationHandlerFactory() {
@Override
public InvocationHandler createInvocationHandler() {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
int pos = (int) args[0];
if (pos == 18 || pos == 19 || pos == 20 || pos == 17) {
args[0] = 34;
//System.out.println("changed eye or face shot into headshot");
}
return method.invoke(proxy, args);
}
};
}
});*/
// - Remove requirement to bless for Libila taming - //
CtClass ctMethodsCreatures = classPool.get("com.wurmonline.server.behaviours.MethodsCreatures");
Util.instrumentDeclared(thisClass, ctMethodsCreatures, "tame", "isPriest", "$_ = false;");
/*ctMethodsCreatures.getDeclaredMethod("tame").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isPriest")) {
m.replace("$_ = false;");
return;
}
}
});*/
Util.insertBeforeDeclared(thisClass, ctMethodsItems, "getImproveTemplateId", replace);*/
// - Remove fatiguing actions requiring you to be on the ground - //
CtClass ctAction = classPool.get("com.wurmonline.server.behaviours.Action");
@@ -476,7 +233,16 @@ public class MiscChanges {
constructor.instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isFatigue")) {
m.replace("$_ = false;");
m.replace("" +
"if(com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" if(!com.wurmonline.server.behaviours.Actions.isActionDestroy(this.getNumber())){" +
" $_ = false;" +
" }else{" +
" $_ = $proceed($$);" +
" }" +
"}else{" +
" $_ = false;" +
"}");
logger.info("Set isFatigue to false in action constructor.");
}
}
@@ -490,7 +256,7 @@ public class MiscChanges {
public void edit(FieldAccess fieldAccess) throws CannotCompileException {
if (Objects.equals("baseCombatRating", fieldAccess.getFieldName()))
fieldAccess.replace("$_ = 1.0f;");
//logger.info("Instrumented Mission Ruler to display all creatures.");
logger.info("Instrumented Mission Ruler to display all creatures.");
}
});
@@ -509,116 +275,16 @@ public class MiscChanges {
+ "}";
Util.instrumentDeclared(thisClass, ctCombatHandler, "checkShield", "max", replace);
Util.setReason("Allow ghost creatures to breed (Chargers).");
Util.instrumentDeclared(thisClass, ctMethodsCreatures, "breed", "isGhost", "$_ = false;");
Util.setReason("Allow Life Transfer to stack with Rotting Touch.");
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);
/* - REMOVED: Added to core game -
Util.setReason("Fix dragon armour dropping on logout.");
Util.instrumentDeclared(thisClass, ctItem, "sleep", "isDragonArmour", "$_ = false;");
Util.setReason("Fix dragon armour dropping on logout.");
Util.instrumentDeclared(thisClass, ctItem, "sleepNonRecursive", "isDragonArmour", "$_ = false;");*/
// - Type creatures randomly in the wild - //
CtClass[] params1 = {
CtClass.intType,
CtClass.booleanType,
CtClass.floatType,
CtClass.floatType,
CtClass.floatType,
CtClass.intType,
classPool.get("java.lang.String"),
CtClass.byteType,
CtClass.byteType,
CtClass.byteType,
CtClass.booleanType,
CtClass.byteType,
CtClass.intType
};
String desc1 = Descriptor.ofMethod(ctCreature, params1);
replace = "$10 = "+MiscChanges.class.getName()+".newCreatureType($1, $10);";
Util.insertBeforeDescribed(thisClass, ctCreature, "doNew", desc1, replace);
// - Send rumour messages to discord - //
// [4/1/18] Removed: Merged to DiscordRelay.
/*Util.setReason("Send rumour messages to Discord.");
replace = MiscChanges.class.getName()+".sendRumour(toReturn);"
+ "$proceed($$);";
Util.instrumentDescribed(thisClass, ctCreature, "doNew", desc1, "broadCastSafe", replace);*/
// - Allow custom creatures to be given special names when bred - //
replace = "$_ = "+MiscChanges.class.getName()+".shouldBreedName(this);";
Util.instrumentDeclared(thisClass, ctCreature, "checkPregnancy", "isHorse", replace);
/*ctCreature.getDeclaredMethod("checkPregnancy").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isHorse")) {
m.replace("$_ = mod.sin.wyvern.MiscChanges.shouldBreedName(this);");
return;
}
}
});*/
// - Auto-Genesis a creature born on enchanted grass - //
Util.setReason("Auto-Genesis a creature born on enchanted grass");
replace = MiscChanges.class.getName()+".checkEnchantedBreed(newCreature);"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCreature, "checkPregnancy", "saveCreatureName", replace);
/*ctCreature.getDeclaredMethod("checkPregnancy").instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("saveCreatureName")) {
m.replace("mod.sin.wyvern.MiscChanges.checkEnchantedBreed(newCreature);"
+ "$_ = $proceed($$);");
return;
}
}
});*/
// - Allow statuettes to be used for casting even when not silver/gold - //
String desc2 = Descriptor.ofMethod(CtClass.booleanType, new CtClass[]{});
Util.setBodyDescribed(thisClass, ctItem, "isHolyItem", desc2, "return this.template.holyItem;");
//ctItem.getMethod("isHolyItem", desc2).setBody("return this.template.holyItem;");
// - Allow GM's to bypass the 5 second emote sound limit. - //
replace = "if(this.getPower() > 0){"
+ " return true;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctPlayer, "mayEmote", replace);
/*ctPlayer.getDeclaredMethod("mayEmote").insertBefore(""
+ "if(this.getPower() > 0){"
+ " return true;"
+ "}");*/
// - Allow archery against ghost targets - //
CtClass ctArchery = classPool.get("com.wurmonline.server.combat.Archery");
CtMethod[] archeryAttacks = ctArchery.getDeclaredMethods("attack");
for(CtMethod method : archeryAttacks){
method.instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isGhost")) {
m.replace("$_ = false;");
logger.info("Enabled archery against ghost targets in archery attack method.");
}
}
});
}
// - Prevent archery altogether against certain creatures - //
CtClass[] params3 = {
ctCreature,
ctCreature,
ctItem,
CtClass.floatType,
ctAction
};
String desc3 = Descriptor.ofMethod(CtClass.booleanType, params3);
replace = "if("+MethodsBestiary.class.getName()+".isArcheryImmune($1, $2)){"
+ " return true;"
+ "}";
Util.insertBeforeDescribed(thisClass, ctArchery, "attack", desc3, replace);
// - Make creatures wander slightly if they are shot from afar by an arrow - //
CtClass ctArrows = classPool.get("com.wurmonline.server.combat.Arrows");
@@ -632,42 +298,6 @@ public class MiscChanges {
Util.insertBeforeDeclared(thisClass, ctPlayers, "broadCastDeathInfo", MiscChanges.class.getName()+".broadCastDeaths($1, $2);");
//ctPlayers.getDeclaredMethod("broadCastDeathInfo").insertBefore("mod.sin.wyvern.MiscChanges.broadCastDeaths($1, $2);");
// - Reduce meditation cooldowns - //
CtClass ctCultist = classPool.get("com.wurmonline.server.players.Cultist");
replace = "return this.path == 1 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayRefresh", replace);
//ctCultist.getDeclaredMethod("mayRefresh").setBody("return this.path == 1 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > 28800000;");
replace = "return this.path == 1 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayEnchantNature", replace);
//ctCultist.getDeclaredMethod("mayEnchantNature").setBody("return this.path == 1 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 28800000;");
replace = "return this.path == 1 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartLoveEffect", replace);
//ctCultist.getDeclaredMethod("mayStartLoveEffect").setBody("return this.path == 1 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > 14400000;");
replace = "return this.path == 2 && this.level > 6 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartDoubleWarDamage", replace);
//ctCultist.getDeclaredMethod("mayStartDoubleWarDamage").setBody("return this.path == 2 && this.level > 6 && System.currentTimeMillis() - this.cooldown1 > 21600000;");
replace = "return this.path == 2 && this.level > 3 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartDoubleStructDamage", replace);
//ctCultist.getDeclaredMethod("mayStartDoubleStructDamage").setBody("return this.path == 2 && this.level > 3 && System.currentTimeMillis() - this.cooldown2 > 14400000;");
replace = "return this.path == 2 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartFearEffect", replace);
//ctCultist.getDeclaredMethod("mayStartFearEffect").setBody("return this.path == 2 && this.level > 8 && System.currentTimeMillis() - this.cooldown3 > 21600000;");
replace = "return this.path == 5 && this.level > 8 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*6)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartNoElementalDamage", replace);
//ctCultist.getDeclaredMethod("mayStartNoElementalDamage").setBody("return this.path == 5 && this.level > 8 && System.currentTimeMillis() - this.cooldown1 > 21600000;");
replace = "return this.path == 5 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*8)+";";
Util.setBodyDeclared(thisClass, ctCultist, "maySpawnVolcano", replace);
//ctCultist.getDeclaredMethod("maySpawnVolcano").setBody("return this.path == 5 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 28800000;");
replace = "return this.path == 5 && this.level > 3 && System.currentTimeMillis() - this.cooldown3 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayStartIgnoreTraps", replace);
//ctCultist.getDeclaredMethod("mayStartIgnoreTraps").setBody("return this.path == 5 && this.level > 3 && System.currentTimeMillis() - this.cooldown3 > 14400000;");
replace = "return this.path == 3 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayCreatureInfo", replace);
//ctCultist.getDeclaredMethod("mayCreatureInfo").setBody("return this.path == 3 && this.level > 3 && System.currentTimeMillis() - this.cooldown1 > 14400000;");
replace = "return this.path == 3 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > "+(TimeConstants.HOUR_MILLIS*4)+";";
Util.setBodyDeclared(thisClass, ctCultist, "mayInfoLocal", replace);
//ctCultist.getDeclaredMethod("mayInfoLocal").setBody("return this.path == 3 && this.level > 6 && System.currentTimeMillis() - this.cooldown2 > 14400000;");
Util.setReason("Adjust weapon damage type based on the potion/salve applied.");
replace = "int wt = mod.sin.wyvern.MiscChanges.getWeaponType($1);"
+ "if(wt != -1){"
@@ -735,50 +365,6 @@ public class MiscChanges {
}
});
Util.setReason("Increase deed upkeep by modifying the amount of tiles it thinks it has.");
CtClass ctGuardPlan = classPool.get("com.wurmonline.server.villages.GuardPlan");
replace = "$_ = "+MiscChanges.class.getName()+".getNewVillageTiles(vill.getNumTiles());";
Util.instrumentDeclared(thisClass, ctGuardPlan, "getMonthlyCost", "getNumTiles", replace);
Util.setReason("Adjust value for certain items.");
replace = "int newVal = "+MiscChanges.class.getName()+".getNewValue(this);"
+ "if(newVal > 0){"
+ " return newVal;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctItem, "getValue", replace);
//Util.setReason("Fix Glimmersteel & Adamantine veins from being depleted rapidly.");
CtClass ctCaveWallBehaviour = classPool.get("com.wurmonline.server.behaviours.CaveWallBehaviour");
CtClass[] params6 = {
ctAction,
ctCreature,
ctItem,
CtClass.intType,
CtClass.intType,
CtClass.booleanType,
CtClass.intType,
CtClass.intType,
CtClass.intType,
CtClass.shortType,
CtClass.floatType
};
String desc6 = Descriptor.ofMethod(CtClass.booleanType, params6);
// [3/27] Removed: Merged to ServerTweaks.
/*replace = "resource = com.wurmonline.server.Server.getCaveResource(tilex, tiley);"
+ "if (resource == 65535) {"
+ " resource = com.wurmonline.server.Server.rand.nextInt(10000);"
+ "}"
+ "if (resource > 1000 && (itemTemplateCreated == 693 || itemTemplateCreated == 697)) {"
+ " resource = com.wurmonline.server.Server.rand.nextInt(1000);"
+ "}"
+ "$_ = $proceed($$);";
Util.instrumentDescribed(thisClass, ctCaveWallBehaviour, "action", desc6, "getDifficultyForTile", replace);*/
Util.setReason("Allow players to mine directly to BSB's in vehicles.");
replace = "$_ = null;"
+ MiscChanges.class.getName()+".miningHook(performer, newItem);";
Util.instrumentDescribed(thisClass, ctCaveWallBehaviour, "action", desc6, "putItemInfrontof", replace);
// -- Identify players making over 10 commands per second and causing the server log message -- //
CtClass ctCommunicator = classPool.get("com.wurmonline.server.creatures.Communicator");
replace = "$_ = $proceed($$);"
@@ -787,21 +373,6 @@ public class MiscChanges {
+ "}";
Util.instrumentDeclared(thisClass, ctCommunicator, "reallyHandle_CMD_ITEM_CREATION_LIST", "log", replace);
Util.setReason("Allow ghost creatures to drop corpses.");
replace = "if("+MiscChanges.class.getName()+".isGhostCorpse(this)){"
+ " $_ = false;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "isGhost", replace);
Util.setReason("Set custom corpse sizes.");
replace = "$_ = $proceed($$);"
+ "if("+MiscChanges.class.getName()+".hasCustomCorpseSize(this)){"
+ " "+MiscChanges.class.getName()+".setCorpseSizes(this, corpse);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "addItem", replace);
Util.setReason("Fix permissions in structures so players cannot cast spells unless they have enter permission.");
CtClass ctStructure = classPool.get("com.wurmonline.server.structures.Structure");
replace = "if(com.wurmonline.server.behaviours.Actions.isActionDietySpell(action)){"
@@ -820,21 +391,200 @@ public class MiscChanges {
+ "}";
Util.setBodyDeclared(thisClass, ctServer, "getBuffedQualityEffect", replace);
/*Util.setReason("Fix Oakshell glance rates from going above 100% when cast power is above 100.");
replace = "if(defender.getBonusForSpellEffect((byte)22) >= 0.0f){"
+ " evasionChance = Math.min(0.4f, evasionChance);"
+ "}"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "isTowerBasher", replace);*/
// double advanceMultiplicator, boolean decay, float times, boolean useNewSystem, double skillDivider)
CtClass[] params = {
CtClass.doubleType,
CtClass.booleanType,
CtClass.floatType,
CtClass.booleanType,
CtClass.doubleType
};
String desc = Descriptor.ofMethod(CtClass.voidType, params);
double minRate = 1.0D;
double maxRate = 8.0D;
double newPower = 2.5;
/*Util.setReason("Ensure players always deal a wound and are not limited by 'does no real damage' messages.");
replace = MiscChanges.class.getName()+".setDefDamage(this.creature, defdamage);"
+ "defdamage = 99999d;"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "isTowerBasher", replace);
replace = "defdamage = "+MiscChanges.class.getName()+".getDefDamage(this.creature);"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "getBattle", replace);*/
Util.setReason("Adjust skill rate to a new, dynamic rate system.");
replace = "double minRate = " + String.valueOf(minRate) + ";" +
"double maxRate = " + String.valueOf(maxRate) + ";" +
"double newPower = " + String.valueOf(newPower) + ";" +
"$1 = $1*(minRate+(maxRate-minRate)*Math.pow((100-this.knowledge)*0.01, newPower));";
Util.insertBeforeDescribed(thisClass, ctSkill,"alterSkill", desc, replace);
Util.setReason("Adjust the amount of scale/hide to distribute after a slaying (1/5).");
replace = "{ return (1.0f + (float)$1.getWeightGrams() * $2)*0.2f; }";
Util.setBodyDeclared(thisClass, ctCreature, "calculateDragonLootTotalWeight", replace);
CtClass ctCargoTransportationMethods = classPool.get("com.wurmonline.server.behaviours.CargoTransportationMethods");
Util.setReason("Disable strength requirement checks for load/unload.");
replace = "{ return true; }";
Util.setBodyDeclared(thisClass, ctCargoTransportationMethods, "strengthCheck", replace);
Util.setReason("Reduce chance of lockpicks breaking.");
replace = "$_ = 40f + $proceed($$);";
Util.instrumentDeclared(thisClass, ctMethodsItems, "checkLockpickBreakage", "getCurrentQualityLevel", replace);
CtClass ctTileBehaviour = classPool.get("com.wurmonline.server.behaviours.TileBehaviour");
CtMethod[] ctGetBehavioursFors = ctTileBehaviour.getDeclaredMethods("getBehavioursFor");
for(CtMethod method : ctGetBehavioursFors){
method.instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getKingdomTemplateId")) {
m.replace("$_ = 3;");
}
}
});
}
Util.setReason("Enable Mycelium to be absorbed from Freedom Isles.");
replace = "$_ = 3;";
CtClass[] params7 = {
ctAction,
ctCreature,
CtClass.intType,
CtClass.intType,
CtClass.booleanType,
CtClass.intType,
CtClass.shortType,
CtClass.floatType
};
String desc7 = Descriptor.ofMethod(CtClass.booleanType, params7);
Util.instrumentDescribed(thisClass, ctTileBehaviour, "action", desc7, "getKingdomTemplateId", replace);
CtClass ctMethodsStructure = classPool.get("com.wurmonline.server.behaviours.MethodsStructure");
Util.setReason("Allow players to construct larger houses.");
float carpentryMultiplier = 2f;
replace = "if(!com.wurmonline.server.Servers.localServer.PVPSERVER){" +
" $_ = $proceed($$)*"+String.valueOf(carpentryMultiplier)+";" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctMethodsStructure, "hasEnoughSkillToExpandStructure", "getKnowledge", replace);
Util.setReason("Allow players to construct larger houses.");
Util.instrumentDeclared(thisClass, ctMethodsStructure, "hasEnoughSkillToContractStructure", "getKnowledge", replace);
CtClass ctPlayerInfo = classPool.get("com.wurmonline.server.players.PlayerInfo");
Util.setReason("Remove waiting time between converting deity.");
replace = "{ return true; }";
Util.setBodyDeclared(thisClass, ctPlayerInfo, "mayChangeDeity", replace);
CtClass ctBless = classPool.get("com.wurmonline.server.spells.Bless");
Util.setReason("Fix Bless infidel error.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctBless, "precondition", "accepts", replace);
CtClass ctRefresh = classPool.get("com.wurmonline.server.spells.Refresh");
Util.setReason("Fix Refresh infidel error.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctRefresh, "precondition", "accepts", replace);
CtClass ctArmourTypes = classPool.get("com.wurmonline.server.combat.ArmourTypes");
Util.setReason("Use epic armor DR values.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctArmourTypes, "getArmourBaseDR", "isChallengeOrEpicServer", replace);
Util.setReason("Use epic armor effectiveness values.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctArmourTypes, "getArmourEffModifier", "isChallengeOrEpicServer", replace);
Util.setReason("Use epic armor material values.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctArmourTypes, "getArmourMatBonus", "isChallengeOrEpicServer", replace);
CtClass ctArmour = classPool.get("com.wurmonline.server.combat.Armour");
Util.setReason("Use epic armor initialization values.");
replace = "$_ = true;";
Util.instrumentDeclared(thisClass, ctArmour, "initialize", "isChallengeOrEpicServer", replace);
Util.setReason("Reduce power of imbues.");
replace = "$_ = Math.max(-80d, -80d+$2);";
Util.instrumentDeclared(thisClass, ctMethodsItems, "smear", "max", replace);
Util.setReason("Update vehicle speeds reliably.");
replace = "if($1 == 8){" +
" $_ = 0;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctPlayer, "checkVehicleSpeeds", "nextInt", replace);
Util.setReason("Reduce mailing costs by 90%.");
CtClass ctMailSendConfirmQuestion = classPool.get("com.wurmonline.server.questions.MailSendConfirmQuestion");
replace = "$_ = $_ / 10;";
Util.insertAfterDeclared(thisClass, ctMailSendConfirmQuestion, "getCostForItem", replace);
Util.setReason("Remove spam from creature enchantments on zombies.");
CtClass ctCreatureEnchantment = classPool.get("com.wurmonline.server.spells.CreatureEnchantment");
replace = "$_ = false;";
Util.instrumentDeclared(thisClass, ctCreatureEnchantment, "precondition", "isReborn", replace);
Util.setReason("Fix epic mission naming.");
CtClass ctEpicServerStatus = classPool.get("com.wurmonline.server.epic.EpicServerStatus");
replace = "if($2.equals(\"\")){" +
" $2 = com.wurmonline.server.deities.Deities.getDeityName($1);" +
"}";
Util.insertBeforeDeclared(thisClass, ctEpicServerStatus, "generateNewMissionForEpicEntity", replace);
Util.setReason("Remove guard tower guards helping against certain types of enemies.");
CtClass ctGuardTower = classPool.get("com.wurmonline.server.kingdom.GuardTower");
replace = "if($0.isUnique() || "+Titans.class.getName()+".isTitan($0) || "+RareSpawns.class.getName()+".isRareCreature($0)){" +
" $_ = false;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctGuardTower, "alertGuards", "isWithinTileDistanceTo", replace);
Util.setReason("Ensure unique creatures cannot be hitched to vehicles.");
CtClass ctVehicle = classPool.get("com.wurmonline.server.behaviours.Vehicle");
replace = "if($1.isUnique()){" +
" return false;" +
"}";
Util.insertBeforeDeclared(thisClass, ctVehicle, "addDragger", replace);
// Enable Strongwall for Libila and other spells on PvE
CtClass ctSpellGenerator = classPool.get("com.wurmonline.server.spells.SpellGenerator");
ctSpellGenerator.getDeclaredMethod("createSpells").instrument(new ExprEditor() {
@Override
public void edit(FieldAccess fieldAccess) throws CannotCompileException {
if (Objects.equals("PVPSERVER", fieldAccess.getFieldName()))
fieldAccess.replace("$_ = true;");
logger.info("Instrumented SpellGenerator PVPSERVER field to enable all spells.");
}
});
Util.setReason("Make heated food never decay if cooked by a royal cook.");
CtClass ctTempStates = classPool.get("com.wurmonline.server.items.TempStates");
replace = "$_ = $proceed($$);" +
"if(chefMade){" +
" $0.setName(\"royal \"+$0.getName());" +
" $0.setHasNoDecay(true);" +
"}";
Util.instrumentDeclared(thisClass, ctTempStates, "checkForChange", "setName", replace);
Util.setReason("Stop royal food decay.");
// Item parent, int parentTemp, boolean insideStructure, boolean deeded, boolean saveLastMaintained, boolean inMagicContainer, boolean inTrashbin
CtClass[] params11 = {
ctItem,
CtClass.intType,
CtClass.booleanType,
CtClass.booleanType,
CtClass.booleanType,
CtClass.booleanType,
CtClass.booleanType
};
String desc11 = Descriptor.ofMethod(CtClass.booleanType, params11);
replace = "if($0.isFood() && $0.hasNoDecay()){" +
" $_ = false;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDescribed(thisClass, ctItem, "poll", desc11, "setDamage", replace);
Util.setReason("Allow mayors to command abandoned vehicles off their deed.");
replace = "if("+MiscChanges.class.getName()+".checkMayorCommand($0, $1)){" +
" return true;" +
"}";
Util.insertBeforeDeclared(thisClass, ctItem, "mayCommand", replace);
} catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);

View File

@@ -0,0 +1,100 @@
package mod.sin.wyvern;
import com.wurmonline.server.Server;
import com.wurmonline.server.deities.Deities;
import com.wurmonline.server.epic.EpicMission;
import com.wurmonline.server.epic.EpicServerStatus;
import com.wurmonline.server.players.PlayerInfo;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Logger;
public class MissionCreator {
private static Logger logger = Logger.getLogger(MissionCreator.class.getName());
public static void pollMissions(){
int[] deityNums = {
1, 2, 3, 4, // Original Gods
6, 7, 8, 9, 10, 11, 12 // Valrei Entities
};
EpicServerStatus es = new EpicServerStatus();
EpicMission[] missions = EpicServerStatus.getCurrentEpicMissions();
int i = 0;
while(i < missions.length){
if(missions[i].isCurrent()){
if(missions[i].isCompleted() || missions[i].getEndTime() >= System.currentTimeMillis()){
try {
int entityId = missions[i].getEpicEntityId();
logger.info("Detected an existing current mission for "+Deities.getDeityName(entityId)+" that was completed or expired. Removing now.");
ReflectionUtil.callPrivateMethod(EpicServerStatus.class, ReflectionUtil.getMethod(EpicServerStatus.class, "destroyLastMissionForEntity"), entityId);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
i++;
}
if(EpicServerStatus.getCurrentEpicMissions().length >= deityNums.length){
logger.info("All entities already have a mission. Aborting.");
return;
}
i = 10;
int number = 1;
while(i > 0) {
number = deityNums[Server.rand.nextInt(deityNums.length)];
logger.info("Testing number "+number);
if(EpicServerStatus.getEpicMissionForEntity(number) == null){
logger.info("Has no mission, breaking loop.");
break;
}else{
logger.info("Has mission, finding new number.");
}
i++;
if(i == 0){
logger.info("Ran through 10 possible entities and could not find empty mission. Cancelling.");
return;
}
}
logger.info("Entity number = "+number);
String entityName = Deities.getDeityName(number);
logger.info("Entity name = "+entityName);
int time = 604800;
logger.info("Current epic missions: "+EpicServerStatus.getCurrentEpicMissions().length);
if (EpicServerStatus.getCurrentScenario() != null) {
es.generateNewMissionForEpicEntity(number, entityName, -1, time, EpicServerStatus.getCurrentScenario().getScenarioName(), EpicServerStatus.getCurrentScenario().getScenarioNumber(), EpicServerStatus.getCurrentScenario().getScenarioQuest(), true);
}
}
public static void awardMissionBonus(PlayerInfo info){
try {
info.setMoney(info.money + 2000 + Server.rand.nextInt(2000));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<MissionCreator> thisClass = MissionCreator.class;
String replace;
CtClass ctTriggerEffect = classPool.get("com.wurmonline.server.tutorial.TriggerEffect");
Util.setReason("Give players currency for completing a mission.");
replace = "$_ = $proceed($$);" +
MissionCreator.class.getName()+".awardMissionBonus($0);";
Util.instrumentDeclared(thisClass, ctTriggerEffect, "effect", "addToSleep", replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -0,0 +1,126 @@
package mod.sin.wyvern;
import com.wurmonline.server.NoSuchItemException;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.NoArmourException;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.NoSpaceException;
import com.wurmonline.shared.constants.BodyPartConstants;
import com.wurmonline.shared.constants.Enchants;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
public class MountedChanges {
public static float newCalcHorseShoeBonus(Creature creature){
float factor = 1.0f;
ArrayList<Item> gear = new ArrayList<>();
try {
Item leftFoot = creature.getEquippedItem(BodyPartConstants.LEFT_FOOT);
gear.add(leftFoot);
} catch (NoSuchItemException | NoSpaceException ignored) {
}
try {
Item rightFoot = creature.getEquippedItem(BodyPartConstants.RIGHT_FOOT);
gear.add(rightFoot);
} catch (NoSuchItemException | NoSpaceException ignored) {
}
try {
Item leftHand = creature.getEquippedItem(BodyPartConstants.LEFT_HAND);
gear.add(leftHand);
} catch (NoSuchItemException | NoSpaceException ignored) {
}
try {
Item rightHand = creature.getEquippedItem(BodyPartConstants.RIGHT_HAND);
gear.add(rightHand);
} catch (NoSuchItemException | NoSpaceException ignored) {
}
try {
Item rightHand = creature.getEquippedItem(BodyPartConstants.RIGHT_HAND);
gear.add(rightHand);
} catch (NoSuchItemException | NoSpaceException ignored) {
}
for(Item shoe : gear){
factor += Math.max(10f, shoe.getCurrentQualityLevel()) / 2000f;
factor += shoe.getSpellSpeedBonus() / 2000f;
factor += shoe.getRarity() * 0.03f;
}
return factor;
}
public static float newMountSpeedMultiplier(Creature creature, boolean mounting){
float hunger = creature.getStatus().getHunger()/65535f;
float damage = creature.getStatus().damage/65535f;
float factor = ((((1f-damage*damage)*(1f-damage)+(1f-2f*damage)*damage)*(1f-damage)+(1f-damage)*damage)*(1f-0.4f*hunger*hunger));
try {
float traitMove = ReflectionUtil.callPrivateMethod(creature, ReflectionUtil.getMethod(creature.getClass(), "getTraitMovePercent"), mounting);
factor += traitMove;
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
if(creature.isHorse() || creature.isUnicorn()) {
factor *= newCalcHorseShoeBonus(creature);
}
if(creature.isHorse()){
try {
Item barding = creature.getArmour(BodyPartConstants.TORSO);
if(barding != null){
if(barding.getTemplateId() == ItemList.clothBarding){
factor *= 0.9f;
}else if(barding.getTemplateId() == ItemList.leatherBarding){
factor *= 0.75f;
}else if(barding.getTemplateId() == ItemList.chainBarding){
factor *= 0.6f;
}
}
} catch (NoArmourException | NoSpaceException e) {
}
}
if (creature.getBonusForSpellEffect(Enchants.CRET_OAKSHELL) > 0.0f) {
factor *= 1f - (0.3f * (creature.getBonusForSpellEffect(Enchants.CRET_OAKSHELL) / 100.0f));
}
if(creature.isRidden()){
try {
float saddleFactor = 1.0f;
Item saddle = creature.getEquippedItem(BodyPartConstants.TORSO);
if(saddle != null) {
saddleFactor += Math.max(10f, saddle.getCurrentQualityLevel()) / 2000f;
saddleFactor += saddle.getSpellSpeedBonus() / 2000f;
saddleFactor += saddle.getRarity() * 0.03f;
factor *= saddleFactor;
}
} catch (NoSuchItemException | NoSpaceException ignored) {
}
}
return factor;
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<MountedChanges> thisClass = MountedChanges.class;
String replace;
Util.setReason("Scaling horse speed.");
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
replace = "{ return "+MountedChanges.class.getName()+".newMountSpeedMultiplier(this, $1); }";
Util.setBodyDeclared(thisClass, ctCreature, "getMountSpeedPercent", replace);
Util.setReason("Force mount speed change check on damage.");
replace = "forceMountSpeedChange();";
Util.insertBeforeDeclared(thisClass, ctCreature, "setWounded", replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -0,0 +1,58 @@
package mod.sin.wyvern;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.players.Player;
import com.wurmonline.server.players.Titles;
import java.util.ArrayList;
import java.util.HashMap;
public class PlayerTitles {
protected static ArrayList<String> donatorTitles = new ArrayList<>();
protected static HashMap<String,Integer> customTitles = new HashMap<>();
protected static HashMap<String,String> playerTitles = new HashMap<>();
public static boolean hasCustomTitle(Creature creature){
if(creature instanceof Player){
Player p = (Player) creature;
return playerTitles.containsKey(p.getName());
}
return false;
}
public static String getCustomTitle(Creature creature){
if(creature instanceof Player){
Player p = (Player) creature;
return " <"+playerTitles.get(p.getName())+">";
}
return "";
}
public static void awardCustomTitles(Player p){
String name = p.getName();
if(donatorTitles.contains(name)){
Titles.Title donator = Titles.Title.getTitle(800);
p.addTitle(donator);
}
if(customTitles.containsKey(name)){
Titles.Title customTitle = Titles.Title.getTitle(customTitles.get(name));
p.addTitle(customTitle);
}
}
public static void preInit(){
playerTitles.put("Sindusk", "Phenomenal Feline");
customTitles.put("Sindawn", 501); // Developer
playerTitles.put("Sindawn", "Pet Me");
donatorTitles.add("Pazza");
customTitles.put("Pazza", 801); // Sindusks Favorite GM
donatorTitles.add("Warriorgen");
customTitles.put("Warriorgen", 802);
donatorTitles.add("Eternallove");
customTitles.put("Eternallove", 803);
donatorTitles.add("Bambam");
customTitles.put("Bambam", 804);
donatorTitles.add("Svenja");
customTitles.put("Svenja", 805);
playerTitles.put("Svenja", "Akuma");
}
}

View File

@@ -0,0 +1,155 @@
package mod.sin.wyvern;
import com.wurmonline.server.Items;
import com.wurmonline.server.NoSuchItemException;
import com.wurmonline.server.NoSuchPlayerException;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.NoSuchCreatureException;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.zones.NoSuchZoneException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.logging.Logger;
public class QualityOfLife {
public static Logger logger = Logger.getLogger(QualityOfLife.class.getName());
public static boolean insertItemIntoVehicle(Item item, Item vehicle, Creature performer) {
// If can put into crates, try that
if (item.getTemplate().isBulk() && item.getRarity() == 0) {
for (Item container : vehicle.getAllItems(true)) {
if (container.getTemplateId() == ItemList.bulkContainer) {
if (container.getFreeVolume() >= item.getVolume()) {
if (item.AddBulkItem(performer, container)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s in your %s.", item.getName(), container.getName(), vehicle.getName()));
return true;
}
}
}
}
for (Item container : vehicle.getAllItems(true)) {
if (container.isCrate() && container.canAddToCrate(item)) {
if (item.AddBulkItemToCrate(performer, container)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s in your %s.", item.getName(), container.getName(), vehicle.getName()));
return true;
}
}
}
}
// No empty crates or disabled, try the vehicle itself
if (vehicle.getNumItemsNotCoins() < 100 && vehicle.getFreeVolume() >= item.getVolume() && vehicle.insertItem(item)) {
performer.getCommunicator().sendNormalServerMessage(String.format("You put the %s in the %s.", item.getName(), vehicle.getName()));
return true;
} else {
// Send message if the vehicle is too full
performer.getCommunicator().sendNormalServerMessage(String.format("The %s is too full to hold the %s.", vehicle.getName(), item.getName()));
return false;
}
}
public static Item getVehicleSafe(Creature pilot) {
try {
if (pilot.getVehicle() != -10)
return Items.getItem(pilot.getVehicle());
} catch (NoSuchItemException ignored) {
}
return null;
}
public static void vehicleHook(Creature performer, Item item){
Item vehicleItem = getVehicleSafe(performer);
if(vehicleItem != null && vehicleItem.isHollow()){
if(insertItemIntoVehicle(item, vehicleItem, performer)){
return;
}
}
// Last resort, if no suitable vehicle is found.
try {
item.putItemInfrontof(performer);
} catch (NoSuchCreatureException | NoSuchItemException | NoSuchPlayerException | NoSuchZoneException e) {
e.printStackTrace();
}
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<QualityOfLife> thisClass = QualityOfLife.class;
String replace;
Util.setReason("Allow players to mine directly into vehicles.");
CtClass ctAction = classPool.get("com.wurmonline.server.behaviours.Action");
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
CtClass ctItem = classPool.get("com.wurmonline.server.items.Item");
CtClass ctCaveWallBehaviour = classPool.get("com.wurmonline.server.behaviours.CaveWallBehaviour");
CtClass[] params1 = {
ctAction,
ctCreature,
ctItem,
CtClass.intType,
CtClass.intType,
CtClass.booleanType,
CtClass.intType,
CtClass.intType,
CtClass.intType,
CtClass.shortType,
CtClass.floatType
};
String desc1 = Descriptor.ofMethod(CtClass.booleanType, params1);
replace = "$_ = null;"
+ QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDescribed(thisClass, ctCaveWallBehaviour, "action", desc1, "putItemInfrontof", replace);
/*Util.setReason("Allow players to surface mine directly into vehicles.");
CtClass ctTileRockBehaviour = classPool.get("com.wurmonline.server.behaviours.TileRockBehaviour");
CtClass[] params2 = {
ctAction,
ctCreature,
ctItem,
CtClass.intType,
CtClass.intType,
CtClass.booleanType,
CtClass.intType,
CtClass.intType,
CtClass.shortType,
CtClass.floatType
};
String desc2 = Descriptor.ofMethod(CtClass.booleanType, params2);
replace = "$_ = $proceed($$);" +
QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDescribed(thisClass, ctTileRockBehaviour, "action", desc2, "setDataXY", replace);*/
Util.setReason("Allow players to surface mine directly into vehicles.");
CtClass ctTileRockBehaviour = classPool.get("com.wurmonline.server.behaviours.TileRockBehaviour");
replace = "$_ = $proceed($$);" +
QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDeclared(thisClass, ctTileRockBehaviour, "mine", "setDataXY", replace);
Util.setReason("Allow players to chop logs directly into vehicles.");
CtClass ctMethodsItems = classPool.get("com.wurmonline.server.behaviours.MethodsItems");
replace = "$_ = null;" +
QualityOfLife.class.getName()+".vehicleHook(performer, $0);";
Util.instrumentDeclared(thisClass, ctMethodsItems, "chop", "putItemInfrontof", replace);
Util.setReason("Allow statuettes to be used when not gold/silver.");
String desc100 = Descriptor.ofMethod(CtClass.booleanType, new CtClass[]{});
replace = "{ return this.template.holyItem; }";
Util.setBodyDescribed(thisClass, ctItem, "isHolyItem", desc100, replace);
Util.setReason("Remove requirement for Libila priests to bless creatures before taming.");
CtClass ctMethodsCreatures = classPool.get("com.wurmonline.server.behaviours.MethodsCreatures");
replace = "$_ = false;";
Util.instrumentDeclared(thisClass, ctMethodsCreatures, "tame", "isPriest", replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -0,0 +1,153 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.Server;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.Creatures;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.creatures.Reaper;
import mod.sin.creatures.SpectralDrake;
import mod.sin.creatures.WyvernBlue;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.ArrayList;
import java.util.logging.Logger;
public class RareSpawns {
public static Logger logger = Logger.getLogger(RareSpawns.class.getName());
public static boolean isRareCreature(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == SpectralDrake.templateId){
return true;
}else if(templateId == Reaper.templateId){
return true;
}
return false;
}
public static void spawnRandomLocationCreature(int templateId){
boolean found = false;
int spawnX = 2048;
int spawnY = 2048;
while(!found){
int x = Server.rand.nextInt(Server.surfaceMesh.getSize());
int y = Server.rand.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
if(height > 0 && height < 1000 && Creature.getTileSteepness(x, y, true)[1] < 30){
Village v = Villages.getVillage(x, y, true);
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
if(v != null){
break;
}
}
}
if(v != null){
continue;
}
spawnX = x*4;
spawnY = y*4;
found = true;
}
}
try {
logger.info("Spawning new rare creature at "+(spawnX*0.25f)+", "+(spawnY*0.25f));
Creature.doNew(templateId, spawnX, spawnY, 360f*Server.rand.nextFloat(), 0, "", (byte)0);
} catch (Exception e) {
logger.severe("Failed to create Rare Spawn.");
e.printStackTrace();
}
}
public static ArrayList<Creature> rares = new ArrayList<>();
public static void pollRareSpawns(){
Creature[] crets = Creatures.getInstance().getCreatures();
for(Creature c : crets){
if(isRareCreature(c) && !rares.contains(c)){
rares.add(c);
logger.info("Existing rare spawn identified ("+c.getName()+"). Adding to rares list.");
}
}
int i = 0;
while(i < rares.size()){
if(rares.get(i).isDead()){
rares.remove(rares.get(i));
logger.info("Rare spawn was found dead ("+rares.get(i).getName()+"). Removing from rares list.");
}else{
i++;
}
}
if(rares.isEmpty()){
logger.info("No rare spawn was found. Spawning a new one.");
int[] rareTemplates = {Reaper.templateId, SpectralDrake.templateId};
int rareTemplateId = rareTemplates[Server.rand.nextInt(rareTemplates.length)];
spawnRandomLocationCreature(rareTemplateId);
if(WyvernBlue.templateId > 0) {
spawnRandomLocationCreature(WyvernBlue.templateId);
}
}
}
public static void preInit(){
try {
ClassPool classPool = HookManager.getInstance().getClassPool();
Class<RareSpawns> thisClass = RareSpawns.class;
String replace;
/*Util.setReason("Disable casting Smite on titans.");
CtClass ctSmite = classPool.get("com.wurmonline.server.spells.Smite");
replace = "if("+RareSpawns.class.getName()+".isRareCreature($3)){"
+ " $2.getCommunicator().sendNormalServerMessage(\"This creature is immune to Smite.\");"
+ " return false;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctSmite, "precondition", replace);*/
Util.setReason("Disable casting Worm Brains on titans.");
CtClass ctWormBrains = classPool.get("com.wurmonline.server.spells.WormBrains");
replace = "if("+RareSpawns.class.getName()+".isRareCreature($3)){"
+ " $2.getCommunicator().sendNormalServerMessage(\"This creature is immune to Worm Brains.\");"
+ " return false;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctWormBrains, "precondition", replace);
Util.setReason("Increase titan extra damage to pets.");
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);
replace = "if($2.isDominated() && $1 != null && "+RareSpawns.class.getName()+".isRareCreature($1)){" +
//" logger.info(\"Detected rare spawn hit on a pet. Adding damage.\");" +
" $5 = $5 * 2d;" +
"}";
Util.insertBeforeDescribed(thisClass, ctCombatEngine, "addWound", desc1, replace);
}catch (NotFoundException e) {
throw new HookException(e);
}
}
}

View File

@@ -71,7 +71,6 @@ public class Soulstealing {
}
}
public static void pollSoulForges(){
logger.info("Polling eternal reservoirs...");
for(Item item : Items.getAllItems()){
if(item.getTemplateId() == EternalReservoir.templateId){
if(!soulForges.contains(item)){

View File

@@ -1,8 +1,14 @@
package mod.sin.wyvern.arena;
package mod.sin.wyvern;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Logger;
import com.wurmonline.server.economy.Economy;
import mod.sin.items.SorceryFragment;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
@@ -28,16 +34,61 @@ import javassist.CtClass;
import javassist.NotFoundException;
import mod.sin.items.ArenaSupplyDepot;
import mod.sin.items.caches.*;
import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.WyvernMods;
import mod.sin.wyvern.util.ItemUtil;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
public class SupplyDepots {
private static Logger logger = Logger.getLogger(SupplyDepots.class.getName());
public static ArrayList<Item> depots = new ArrayList<Item>();
public static ArrayList<Item> depots = new ArrayList<>();
public static Creature host = null;
public static final long depotRespawnTime = TimeConstants.HOUR_MILLIS*7L;
public static final long depotRespawnTime = TimeConstants.HOUR_MILLIS*11L;
public static long lastSpawnedDepot = 0;
protected static boolean initalizedSupplyDepot = false;
public static void updateLastSpawnedDepot(){
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("UPDATE ObjectiveTimers SET TIMER = " + String.valueOf(System.currentTimeMillis()) + " WHERE ID = \"DEPOT\"");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void initializeDepotTimer(){
Connection dbcon;
PreparedStatement ps;
boolean foundLeaderboardOpt = false;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM ObjectiveTimers WHERE ID = \"DEPOT\"");
ResultSet rs = ps.executeQuery();
lastSpawnedDepot = rs.getLong("TIMER");
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
logger.info("Initialized Supply Depot timer: "+lastSpawnedDepot);
initalizedSupplyDepot = true;
}
public static void addPlayerStatsDepot(String playerName){
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("UPDATE PlayerStats SET DEPOTS = DEPOTS + 1 WHERE NAME = \""+playerName+"\"");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void sendDepotEffect(Player player, Item depot){
player.getCommunicator().sendAddEffect(depot.getWurmId(), (byte) 25, depot.getPosX(), depot.getPosY(), depot.getPosZ(), (byte) 0);
}
@@ -58,9 +109,7 @@ public class SupplyDepots {
}
}
public static void removeSupplyDepot(Item depot){
if(depots.contains(depot)){
depots.remove(depot);
}
removeDepotEffect(depot);
}
private static boolean isSupplyDepot(Item item){
@@ -69,6 +118,9 @@ public class SupplyDepots {
public static void pollDepotSpawn(){
if(!Servers.localServer.PVPSERVER && !WyvernMods.enableDepots){
return;
}
if(!initalizedSupplyDepot){
return;
}
for(int i = 0; i < depots.size(); i++){
Item depot = depots.get(i);
@@ -87,7 +139,7 @@ public class SupplyDepots {
}
if(depots.isEmpty()){
if(host == null){
ArrayList<Creature> uniques = new ArrayList<Creature>();
ArrayList<Creature> uniques = new ArrayList<>();
for(Creature c : Creatures.getInstance().getCreatures()){
if(c.isUnique()){
uniques.add(c);
@@ -95,7 +147,7 @@ public class SupplyDepots {
}
if(uniques.size() > 0){
host = uniques.get(Server.rand.nextInt(uniques.size()));
MiscChanges.sendImportantMessage(host, "Greetings! I'll be your host, informing you of the next depot to appear over here on the Arena!", 255, 128, 0);
MiscChanges.sendGlobalFreedomChat(host, "Greetings! I'll be your host, informing you of the next depot to appear over here on the Arena!", 255, 128, 0);
}
}
if(System.currentTimeMillis() > lastSpawnedDepot + depotRespawnTime){
@@ -105,23 +157,27 @@ public class SupplyDepots {
while(!spawned && i < 20){
float worldSizeX = Zones.worldTileSizeX;
float worldSizeY = Zones.worldTileSizeY;
float minX = worldSizeX*0.25f;
float minY = worldSizeY*0.25f;
int tilex = (int) (minX+(minX*2*Server.rand.nextFloat()));
int tiley = (int) (minY+(minY*2*Server.rand.nextFloat()));
float minX = worldSizeX*0.2f;
float minY = worldSizeY*0.2f;
int tilex = (int) (minX+(minX*3*Server.rand.nextFloat()));
int tiley = (int) (minY+(minY*3*Server.rand.nextFloat()));
int tile = Server.surfaceMesh.getTile(tilex, tiley);
try {
if(Tiles.decodeHeight((int)tile) > 0){
if(Tiles.decodeHeight(tile) > 0){
Item depot = ItemFactory.createItem(ArenaSupplyDepot.templateId, 50+Server.rand.nextFloat()*40f, (float)(tilex << 2) + 2.0f, (float)(tiley << 2) + 2.0f, Server.rand.nextFloat() * 360.0f, true, (byte) 0, -10, null);
depots.add(depot);
sendDepotEffectsToPlayers(depot);
if(host != null){
MiscChanges.sendImportantMessage(host, "A new depot has appeared on the Arena!", 255, 128, 0);
}
logger.info("New supply depot being placed at "+tilex+", "+tiley);
spawned = true;
if(host != null){
MiscChanges.sendServerTabMessage("arena", "A new Arena depot has appeared!", 255, 128, 0);
MiscChanges.sendGlobalFreedomChat(host, "A new Arena depot has appeared!", 255, 128, 0);
}else{
MiscChanges.sendServerTabMessage("arena", "A new Arena depot has appeared!", 255, 128, 0);
}
host = null;
lastSpawnedDepot = System.currentTimeMillis();
updateLastSpawnedDepot();
}else{
logger.info("Position "+tilex+", "+tiley+" was invalid, attempting another spawn...");
i++;
@@ -138,12 +194,13 @@ public class SupplyDepots {
long timeleft = (lastSpawnedDepot + depotRespawnTime) - System.currentTimeMillis();
long minutesLeft = timeleft/TimeConstants.MINUTE_MILLIS;
if(minutesLeft > 0){
if(minutesLeft == 1){
MiscChanges.sendImportantMessage(host, "Come quickly! The next Arena depot will appear in 5 minutes!", 255, 128, 0);
if(minutesLeft == 4){
MiscChanges.sendServerTabMessage("arena", "The next Arena depot will appear in 5 minutes!", 255, 128, 0);
}else if(minutesLeft == 19){
MiscChanges.sendImportantMessage(host, "Best start heading over, the next Arena depot will appear in 20 minutes!", 255, 128, 0);
MiscChanges.sendServerTabMessage("arena", "The next Arena depot will appear in 20 minutes!", 255, 128, 0);
}else if(minutesLeft == 59){
MiscChanges.sendImportantMessage(host, "Heads up! The next Arena depot will appear in 60 minutes!", 255, 128, 0);
MiscChanges.sendServerTabMessage("arena", "The next Arena depot will appear in 60 minutes!", 255, 128, 0);
MiscChanges.sendGlobalFreedomChat(host, "The next Arena depot will appear in 60 minutes!", 255, 128, 0);
}
}
}
@@ -152,45 +209,78 @@ public class SupplyDepots {
public static long lastAttemptedDepotCapture = 0;
public static final long captureMessageInterval = TimeConstants.MINUTE_MILLIS*3L;
public static void broadcastCapture(Creature performer){
MiscChanges.sendServerTabMessage("arena", performer.getName()+" has claimed an Arena depot!", 255, 128, 0);
MiscChanges.sendGlobalFreedomChat(performer, performer.getName()+" has claimed an Arena depot!", 255, 128, 0);
}
public static void maybeBroadcastOpen(Creature performer){
if(System.currentTimeMillis() > lastAttemptedDepotCapture + captureMessageInterval){
MiscChanges.sendImportantMessage(performer, performer.getName()+" is begnning to capture an Arena depot!", 255, 128, 0);
MiscChanges.sendServerTabMessage("arena", performer.getName()+" is beginning to capture an Arena depot!", 255, 128, 0);
MiscChanges.sendGlobalFreedomChat(performer, performer.getName()+" is beginning to capture an Arena depot!", 255, 128, 0);
lastAttemptedDepotCapture = System.currentTimeMillis();
}
}
public static void giveCacheReward(Creature performer){
Item inv = performer.getInventory();
Item enchantOrb = ItemUtil.createEnchantOrb(130f+(Server.rand.nextFloat()*20));
Item enchantOrb = ItemUtil.createEnchantOrb(40f+(Math.min(Server.rand.nextFloat()*40f, Server.rand.nextFloat()*40f)));
if(enchantOrb != null) {
inv.insertItem(enchantOrb);
}
try {
// Sorcery fragment.
Item sorceryFragment = ItemFactory.createItem(SorceryFragment.templateId, 90f, "Depot");
inv.insertItem(sorceryFragment, true);
// Add a special caches as a reward.
int[] cacheIds = {
ArmourCache.templateId,
ArtifactCache.templateId,
CrystalCache.templateId,
DragonCache.templateId,
CrystalCache.templateId, CrystalCache.templateId,
DragonCache.templateId, DragonCache.templateId,
GemCache.templateId,
MoonCache.templateId,
MoonCache.templateId, MoonCache.templateId,
RiftCache.templateId,
TreasureMapCache.templateId
};
int i = 1+Server.rand.nextInt(3); // 2-4 caches extra.
while(i >= 0){
Item cache = ItemFactory.createItem(cacheIds[Server.rand.nextInt(cacheIds.length)], 80f+(20f*Server.rand.nextFloat()), "");
int i = 2+Server.rand.nextInt(2); // 2-3 caches.
while(i > 0){
Item cache = ItemFactory.createItem(cacheIds[Server.rand.nextInt(cacheIds.length)], 20f+(60f*Server.rand.nextFloat()), "");
inv.insertItem(cache, true);
i--;
}
if(Server.rand.nextFloat()*100f <= 10f){
// Add kingdom tokens
i = 3+Server.rand.nextInt(3); // 3-5 kingdom tokens
while(i > 0){
Item token = ItemFactory.createItem(22765, 40f+(50f*Server.rand.nextFloat()), "");
inv.insertItem(token, true);
i--;
}
// Seryll or sleep powder
if(Server.rand.nextBoolean()){
Item seryll = ItemFactory.createItem(ItemList.seryllBar, 70+(30*Server.rand.nextFloat()), null);
inv.insertItem(seryll, true);
}else{
Item sleepPowder = ItemFactory.createItem(ItemList.sleepPowder, 99f, null);
inv.insertItem(sleepPowder, true);
}
// Very low chance for a HotA statue.
if(Server.rand.nextFloat()*100f <= 1f){
Item hotaStatue = ItemFactory.createItem(ItemList.statueHota, 80f+(20f*Server.rand.nextFloat()), "");
hotaStatue.setAuxData((byte)Server.rand.nextInt(10));
hotaStatue.setWeight(50000, true);
inv.insertItem(hotaStatue, true);
}
if(Server.rand.nextFloat()*100f <= 3f){
// Add 10-30 copper
long iron = 1000; // 10 copper
iron += Server.rand.nextInt(2000); // add up to 20 copper
Item[] coins = Economy.getEconomy().getCoinsFor(iron);
for(Item coin : coins){
inv.insertItem(coin, true);
}
/*if(Server.rand.nextFloat()*100f <= 3f){
Item sorcery = ItemFactory.createItem(ItemUtil.sorceryIds[Server.rand.nextInt(ItemUtil.sorceryIds.length)], 80f+(20f*Server.rand.nextFloat()), "");
sorcery.setAuxData((byte)2);
inv.insertItem(sorcery, true);
}
}*/
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
@@ -202,10 +292,10 @@ public class SupplyDepots {
// - Add light effects for the supply depots, since they are unique - //
CtClass ctPlayers = classPool.get("com.wurmonline.server.Players");
ctPlayers.getDeclaredMethod("sendAltarsToPlayer").insertBefore("mod.sin.wyvern.arena.SupplyDepots.sendDepotEffectsToPlayer($1);");
ctPlayers.getDeclaredMethod("sendAltarsToPlayer").insertBefore("mod.sin.wyvern.SupplyDepots.sendDepotEffectsToPlayer($1);");
}catch (CannotCompileException | NotFoundException e) {
throw new HookException((Throwable)e);
throw new HookException(e);
}
}
}

View File

@@ -0,0 +1,122 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.Server;
import com.wurmonline.server.Servers;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.players.PlayerInfo;
import com.wurmonline.server.players.PlayerInfoFactory;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.HashMap;
import java.util.logging.Logger;
public class TeleportHandler {
public static Logger logger = Logger.getLogger(TeleportHandler.class.getName());
protected static HashMap<Long, Float> teleX = new HashMap<>();
protected static HashMap<Long, Float> teleY = new HashMap<>();
protected static void setTeleportLocationRandom(long wurmid){
boolean found = false;
while(!found){
int x = Server.rand.nextInt(Server.surfaceMesh.getSize());
int y = Server.rand.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
if(height > 0 && height < 1000 && Creature.getTileSteepness(x, y, true)[1] < 30){
Village v = Villages.getVillage(x, y, true);
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
if(v != null){
break;
}
}
}
if(v != null){
continue;
}
teleX.put(wurmid, (float) (x*4));
teleY.put(wurmid, (float) (y*4));
found = true;
}
}
}
protected static void setTeleportLocation(long wurmid){
PlayerInfo pinfo = PlayerInfoFactory.getPlayerInfoWithWurmId(wurmid);
if(pinfo != null){
logger.info("Player info exists.");
boolean hasVillage = false;
for(Village v : Villages.getVillages()){
if(v.isCitizen(wurmid)){
logger.info("Player is found in village "+v.getName()+", teleporting to token.");
teleX.put(wurmid, (float) (v.getTokenX()*4));
teleY.put(wurmid, (float) (v.getTokenY()*4));
hasVillage = true;
break;
}
}
if(!hasVillage){
if(Servers.localServer.PVPSERVER) {
logger.info("Player is not identified as belonging to a village. PvP server detected. Performing random teleport.");
setTeleportLocationRandom(wurmid);
}else{
logger.info("Player is not identified as belonging to a village. PvE server detected. Teleporting to JENNX/JENNY.");
teleX.put(wurmid, (float) (Servers.localServer.SPAWNPOINTJENNX*4));
teleY.put(wurmid, (float) (Servers.localServer.SPAWNPOINTJENNY*4));
}
}
}else{
if(Servers.localServer.PVPSERVER) {
logger.info("Player info doesn't exist. PvP server detected. Performing a random teleport.");
setTeleportLocationRandom(wurmid);
}else{
logger.info("Player info doesn't exist. PvE server detected. Teleporting to JENNX/JENNY.");
teleX.put(wurmid, (float) (Servers.localServer.SPAWNPOINTJENNX*4));
teleY.put(wurmid, (float) (Servers.localServer.SPAWNPOINTJENNY*4));
}
}
}
public static float getTeleportPosX(long wurmid){
setTeleportLocation(wurmid);
if(teleX.containsKey(wurmid)){
return teleX.get(wurmid);
}
return 4000f;
}
public static float getTeleportPosY(long wurmid){
if(teleY.containsKey(wurmid)){
return teleY.get(wurmid);
}
return 4000f;
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<TeleportHandler> thisClass = TeleportHandler.class;
String replace;
Util.setReason("Custom teleportation system for Arena teleport/escape.");
CtClass ctPlayerMetaData = classPool.get("com.wurmonline.server.players.PlayerMetaData");
replace = "logger.info(\"posx = \"+this.posx+\", posy = \"+this.posy);" +
"if(this.posx >= 4000f && this.posx <= 4050f && this.posy >= 4000f && this.posy <= 4050f){" +
" this.posx = "+TeleportHandler.class.getName()+".getTeleportPosX(this.wurmid);" +
" this.posy = "+TeleportHandler.class.getName()+".getTeleportPosY(this.wurmid);" +
"}" +
"$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctPlayerMetaData, "save", "getPosition", replace);
} catch ( NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -0,0 +1,855 @@
package mod.sin.wyvern;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.*;
import com.wurmonline.server.bodys.Wound;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.Creatures;
import com.wurmonline.server.creatures.MineDoorPermission;
import com.wurmonline.server.creatures.SpellEffects;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemFactory;
import com.wurmonline.server.items.NoSuchTemplateException;
import com.wurmonline.server.spells.SpellEffect;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import com.wurmonline.server.zones.AreaSpellEffect;
import com.wurmonline.server.zones.VolaTile;
import com.wurmonline.server.zones.Zones;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import mod.sin.creatures.titans.*;
import mod.sin.items.caches.ArtifactCache;
import mod.sin.items.caches.TreasureMapCache;
import mod.sin.lib.Util;
import mod.sin.wyvern.util.ItemUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;
public class Titans {
public static Logger logger = Logger.getLogger(Titans.class.getName());
protected static boolean initializedTitans = false;
public static void updateLastSpawnedTitan(){
Connection dbcon;
PreparedStatement ps;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("UPDATE ObjectiveTimers SET TIMER = " + String.valueOf(System.currentTimeMillis()) + " WHERE ID = \"TITAN\"");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void initializeTitanTimer(){
Connection dbcon;
PreparedStatement ps;
boolean foundLeaderboardOpt = false;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM ObjectiveTimers WHERE ID = \"TITAN\"");
ResultSet rs = ps.executeQuery();
lastSpawnedTitan = rs.getLong("TIMER");
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
logger.info("Initialized Titan timer: "+lastSpawnedTitan);
initializedTitans = true;
}
public static void addTitanLoot(Creature titan){
Item inv = titan.getInventory();
int i = 0;
while(i < 3) {
Item sorcery = ItemUtil.createRandomSorcery((byte) 1);
if (sorcery != null) {
inv.insertItem(sorcery, true);
}
i++;
}
try {
Item cache = ItemFactory.createItem(Server.rand.nextBoolean() ? TreasureMapCache.templateId : ArtifactCache.templateId, 90f+(10f*Server.rand.nextFloat()), titan.getName());
inv.insertItem(cache, true);
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
}
public static void checkDestroyMineDoor(Creature titan, int x, int y){
int tile = Server.surfaceMesh.getTile(x, y);
if(Tiles.isMineDoor(Tiles.decodeType(tile))){
if (Tiles.decodeType(Server.caveMesh.getTile(x, y)) == Tiles.Tile.TILE_CAVE_EXIT.id) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y)), Tiles.Tile.TILE_HOLE.id, (byte) 0);
} else {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y)), Tiles.Tile.TILE_ROCK.id, (byte) 0);
}
Players.getInstance().sendChangedTile(x, y, true, true);
MineDoorPermission.deleteMineDoor(x, y);
Server.getInstance().broadCastAction(titan.getName() + "'s ability destroys a mine door!", titan, 50);
}
}
public static Creature[] getUndergroundCreatures(int x, int y){
VolaTile tCave = Zones.getOrCreateTile(x, y, false);
if(tCave == null){
return null;
}
int tileCave = Server.caveMesh.getTile(x, y);
byte typeCave = Tiles.decodeType(tileCave);
if(typeCave != Tiles.Tile.TILE_CAVE.id && typeCave != Tiles.Tile.TILE_CAVE_EXIT.id && typeCave != Tiles.Tile.TILE_CAVE_FLOOR_REINFORCED.id && typeCave != Tiles.Tile.TILE_CAVE_PREPATED_FLOOR_REINFORCED.id){
return null;
}
return tCave.getCreatures();
}
public static boolean isTitan(int templateId){
if(templateId == Lilith.templateId){
return true;
}else if(templateId == Ifrit.templateId){
return true;
}
return false;
}
public static boolean isTitan(Creature creature){
return isTitan(creature.getTemplate().getTemplateId());
}
public static boolean isTitanMinion(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == LilithWraith.templateId){
return true;
}else if(templateId == LilithZombie.templateId){
return true;
}else if(templateId == IfritFiend.templateId){
return true;
}else if(templateId == IfritSpider.templateId){
return true;
}
return false;
}
// --- Advanced Abilities --- //
public static void lilithMyceliumVoidAttack(Creature titan, Creature lCret, int tilex, int tiley){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)){
return;
}
if (!lCret.addWoundOfType(lCret, Wound.TYPE_INFECTION, 1, true, 1.0f, true, 50000f)) {
Creatures.getInstance().setCreatureDead(lCret);
Players.getInstance().setCreatureDead(lCret);
lCret.setTeleportPoints((short)tilex, (short)tiley, titan.getLayer(), 0);
lCret.startTeleporting();
lCret.getCommunicator().sendAlertServerMessage("You are absorbed by the Mycelium and brought to Lilith!");
lCret.getCommunicator().sendTeleport(false);
if (!lCret.isPlayer()) {
lCret.getMovementScheme().resumeSpeedModifier();
}
}
}
public static void ifritMassIncinerateAttack(Creature titan, Creature lCret){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)){
return;
}
SpellEffect eff;
SpellEffects effs = lCret.getSpellEffects();
if (effs == null) {
effs = lCret.createSpellEffects();
}
eff = effs.getSpellEffect((byte) 94);
if (eff == null) {
lCret.getCommunicator().sendAlertServerMessage("You are engulfed by the flames of Ifrit!", (byte) 4);
eff = new SpellEffect(lCret.getWurmId(), (byte) 94, 80f, 180, (byte) 9, (byte) 1, true);
effs.addSpellEffect(eff);
Server.getInstance().broadCastAction(titan.getName() + " has engulfed " + lCret.getNameWithGenus() + " in flames!", titan, 50);
} else {
lCret.getCommunicator().sendAlertServerMessage("The heat around you increases. The pain is excruciating!", (byte) 4);
eff.setPower(eff.getPower()+200f);
eff.setTimeleft(180);
lCret.sendUpdateSpellEffect(eff);
Server.getInstance().broadCastAction(titan.getName() + " has engulfed " + lCret.getNameWithGenus() + " in flames again, increasing the intensity!", titan, 50);
}
}
public static void performAdvancedAbility(Creature titan, int range, int radius){
int tilex = titan.getTileX();
int tiley = titan.getTileY();
if(titan.getTemplate().getTemplateId() == Lilith.templateId){ // Lilith Ability
int tarx = (tilex-(range))+(Server.rand.nextInt(1+(range*2)));
int tary = (tiley-(range))+(Server.rand.nextInt(1+(range*2)));
int sx = Zones.safeTileX(tarx - radius);
int ex = Zones.safeTileX(tarx + radius);
int sy = Zones.safeTileY(tary - radius);
int ey = Zones.safeTileY(tary + radius);
Zones.flash(tarx, tary, false);
Server.getInstance().broadCastAction(titan.getName() + " casts Mycelium Void, turning the earth to fungus and pulling enemies to "+titan.getHimHerItString()+"!", titan, 50);
for (int x = sx; x <= ex; ++x) {
for (int y = sy; y <= ey; ++y) {
VolaTile t = Zones.getOrCreateTile(x, y, true);
if (t == null){
continue;
}
checkDestroyMineDoor(titan, x, y);
int tile = Server.surfaceMesh.getTile(x, y);
byte type = Tiles.decodeType(tile);
Tiles.Tile theTile = Tiles.getTile(type);
byte data = Tiles.decodeData(tile);
// Copied from Fungus to prevent wacko behaviours like deleting minedoors and glitching tunnels:
if (type != Tiles.Tile.TILE_FIELD.id && type != Tiles.Tile.TILE_FIELD2.id && type != Tiles.Tile.TILE_GRASS.id && type != Tiles.Tile.TILE_REED.id && type != Tiles.Tile.TILE_DIRT.id && type != Tiles.Tile.TILE_LAWN.id && type != Tiles.Tile.TILE_STEPPE.id && !theTile.isNormalTree() && !theTile.isEnchanted() && !theTile.isNormalBush()){
//
}else{
if (theTile.isNormalTree()) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), theTile.getTreeType(data).asMyceliumTree(), data);
} else if (theTile.isEnchantedTree()) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), theTile.getTreeType(data).asNormalTree(), data);
} else if (theTile.isNormalBush()) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), theTile.getBushType(data).asMyceliumBush(), data);
} else if (theTile.isEnchantedBush()) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), theTile.getBushType(data).asNormalBush(), data);
} else if (type == Tiles.Tile.TILE_LAWN.id) {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), Tiles.Tile.TILE_MYCELIUM_LAWN.id, (byte) 0);
} else {
Server.setSurfaceTile(x, y, Tiles.decodeHeight(tile), Tiles.Tile.TILE_MYCELIUM.id, (byte) 0);
}
Players.getInstance().sendChangedTile(x, y, true, false);
}
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
lilithMyceliumVoidAttack(titan, lCret, tilex, tiley);
}
VolaTile tCave = Zones.getOrCreateTile(x, y, false);
if(tCave == null){
continue;
}
int tileCave = Server.caveMesh.getTile(x, y);
byte typeCave = Tiles.decodeType(tileCave);
if(typeCave != Tiles.Tile.TILE_CAVE.id && typeCave != Tiles.Tile.TILE_CAVE_EXIT.id && typeCave != Tiles.Tile.TILE_CAVE_FLOOR_REINFORCED.id && typeCave != Tiles.Tile.TILE_CAVE_PREPATED_FLOOR_REINFORCED.id){
continue;
}
Creature[] crets3 = tCave.getCreatures();
for (Creature lCret : crets3) {
lilithMyceliumVoidAttack(titan, lCret, tilex, tiley);
}
}
}
}else if(titan.getTemplate().getTemplateId() == Ifrit.templateId){ // Ifrit Ability
int tarx = (tilex-range)+(Server.rand.nextInt(1+(range*2)));
int tary = (tiley-range)+(Server.rand.nextInt(1+(range*2)));
int sx = Zones.safeTileX(tarx - radius);
int ex = Zones.safeTileX(tarx + radius);
int sy = Zones.safeTileY(tary - radius);
int ey = Zones.safeTileY(tary + radius);
Zones.flash(tarx, tary, false);
Server.getInstance().broadCastAction(titan.getName() + " casts Mass Incinerate, burning enemies near "+titan.getHimHerItString()+"!", titan, 50);
for (int x = sx; x <= ex; ++x) {
for (int y = sy; y <= ey; ++y) {
VolaTile t = Zones.getOrCreateTile(x, y, true);
if (t == null){
continue;
}
checkDestroyMineDoor(titan, x, y);
new AreaSpellEffect(titan.getWurmId(), x, y, titan.getLayer(), (byte) 35, System.currentTimeMillis() + 5000, 200.0f, titan.getLayer(), 0, true);
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
ifritMassIncinerateAttack(titan, lCret);
}
Creature[] undergroundCreatures = getUndergroundCreatures(x, y);
if(undergroundCreatures != null){
for(Creature lCret : undergroundCreatures){
ifritMassIncinerateAttack(titan, lCret);
}
}
}
}
}
}
// --- Basic Abilities --- //
public static void lilithPainRainAttack(Creature titan, Creature lCret, VolaTile t){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)){
return;
}
t.sendAttachCreatureEffect(lCret, (byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 0);
try {
if (lCret.addWoundOfType(titan, Wound.TYPE_INFECTION, lCret.getBody().getRandomWoundPos(), false, 1.0f, false, 25000.0 * (double)lCret.addSpellResistance((short) 448))){
return;
}
} catch (Exception e) {
e.printStackTrace();
}
lCret.setTarget(titan.getWurmId(), false);
}
public static void performBasicAbility(Creature titan){
int tilex = titan.getTileX();
int tiley = titan.getTileY();
if(titan.getTemplate().getTemplateId() == Lilith.templateId){ // Lilith Ability
int sx = Zones.safeTileX(tilex - 10);
int sy = Zones.safeTileY(tiley - 10);
int ex = Zones.safeTileX(tilex + 10);
int ey = Zones.safeTileY(tiley + 10);
//this.calculateArea(sx, sy, ex, ey, tilex, tiley, layer, currstr);
int x, y;
Server.getInstance().broadCastAction(titan.getName() + " casts Pain Rain, harming all around "+titan.getHimHerItString()+"!", titan, 50);
for (x = sx; x <= ex; ++x) {
for (y = sy; y <= ey; ++y) {
VolaTile t = Zones.getTileOrNull(x, y, titan.isOnSurface());
if (t == null){
continue;
}
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
lilithPainRainAttack(titan, lCret, t);
}
Creature[] undergroundCreatures = getUndergroundCreatures(x, y);
if(undergroundCreatures != null){
for(Creature lCret : undergroundCreatures){
lilithPainRainAttack(titan, lCret, t);
}
}
}
}
}else if(titan.getTemplate().getTemplateId() == Ifrit.templateId){ // Ifrit Ability
int sx = Zones.safeTileX(tilex - 10);
int sy = Zones.safeTileY(tiley - 10);
int ex = Zones.safeTileX(tilex + 10);
int ey = Zones.safeTileY(tiley + 10);
int x, y;
ArrayList<Creature> targets = new ArrayList<>();
for (x = sx; x <= ex; ++x) {
for (y = sy; y <= ey; ++y) {
VolaTile t = Zones.getTileOrNull(x, y, titan.isOnSurface());
if (t == null){
continue;
}
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)){
continue;
}
targets.add(lCret);
}
Creature[] undergroundCreatures = getUndergroundCreatures(x, y);
if(undergroundCreatures != null){
for(Creature lCret : undergroundCreatures){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)){
continue;
}
targets.add(lCret);
}
}
}
}
if(!targets.isEmpty()){
Creature target = null;
for(Creature cret : targets){
if(cret.isHitched() || cret.isRidden()){
target = cret;
break;
}
}
if(target == null){
for(Creature cret : targets){
if(cret.isPlayer()){
target = cret;
break;
}
}
}
if(target == null) {
target = targets.get(Server.rand.nextInt(targets.size()));
}
if(target == null){
logger.info("Something went absolutely horribly wrong and there is no target for the Titan.");
}
int damage = target.getStatus().damage;
int minhealth = 65435;
float maxdam = (float)Math.max(0, minhealth - damage);
if (maxdam > 500.0f) {
Server.getInstance().broadCastAction(titan.getName() + " picks a target at random and Smites "+target.getName()+"!", titan, 50);
target.getCommunicator().sendAlertServerMessage(titan.getName() + " smites you.", (byte) 4);
try {
target.addWoundOfType(titan, Wound.TYPE_BURN, target.getBody().getRandomWoundPos(), false, 1.0f, false, maxdam);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public static void summonChampions(Creature titan, int nums){
int templateType = -10;
String spellName = "";
if(titan.getTemplate().getTemplateId() == Lilith.templateId){
templateType = LilithWraith.templateId;
spellName = "Raise Wraith";
}else if(titan.getTemplate().getTemplateId() == Ifrit.templateId){
templateType = IfritFiend.templateId;
spellName = "Summon Fiend";
}
if(templateType == -10){
logger.severe("[ERROR]: Template type not set in summonChampions()");
return;
}
try {
Server.getInstance().broadCastAction(titan.getName() + " casts "+spellName+", calling champions to "+titan.getHimHerItString()+" aid!", titan, 50);
for(int i = 0; i < nums; i++){
int tilex = ((titan.getTileX()*4)+3)-Server.rand.nextInt(7);
int tiley = ((titan.getTileY()*4)+3)-Server.rand.nextInt(7);
int sx = Zones.safeTileX(tilex - 2);
int sy = Zones.safeTileY(tiley - 2);
int ex = Zones.safeTileX(tilex + 2);
int ey = Zones.safeTileY(tiley + 2);
Creature target = null;
for (int x = sx; x <= ex; ++x) {
for (int y = sy; y <= ey; ++y) {
VolaTile t = Zones.getTileOrNull(x, y, titan.isOnSurface());
if (t == null){
continue;
}
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)) continue;
if(Server.rand.nextInt(3) == 0){
target = lCret;
break;
}
}
Creature[] undergroundCreatures = getUndergroundCreatures(x, y);
if(undergroundCreatures != null){
for(Creature lCret : undergroundCreatures){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)) continue;
if(Server.rand.nextInt(3) == 0){
target = lCret;
break;
}
}
}
if(target != null){
break;
}
}
if(target != null){
break;
}
}
// public static Creature doNew(int templateid, float aPosX, float aPosY, float aRot, int layer, String name, byte gender) throws Exception {
Creature champion = Creature.doNew(templateType, tilex, tiley, 360f*Server.rand.nextFloat(), titan.getLayer(), "", (byte)0);
if(target != null){
champion.setOpponent(target);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void summonMinions(Creature titan, int nums){
int templateType = -10;
String spellName = "";
if(titan.getTemplate().getTemplateId() == Lilith.templateId){
templateType = LilithZombie.templateId;
spellName = "Raise Zombie";
}else if(titan.getTemplate().getTemplateId() == Ifrit.templateId){
templateType = IfritSpider.templateId;
spellName = "Summon Spider";
}
if(templateType == -10){
logger.severe("[ERROR]: Template type not set in summonMinions()");
return;
}
try {
Server.getInstance().broadCastAction(titan.getName() + " casts "+spellName+", calling minions to "+titan.getHimHerItString()+" aid!", titan, 50);
for(int i = 0; i < nums; i++){
int tilex = ((titan.getTileX()*4)+3)-Server.rand.nextInt(7);
int tiley = ((titan.getTileY()*4)+3)-Server.rand.nextInt(7);
int sx = Zones.safeTileX(tilex - 10);
int sy = Zones.safeTileY(tiley - 10);
int ex = Zones.safeTileX(tilex + 10);
int ey = Zones.safeTileY(tiley + 10);
Creature target = null;
for (int x = sx; x <= ex; ++x) {
for (int y = sy; y <= ey; ++y) {
VolaTile t = Zones.getTileOrNull(x, y, titan.isOnSurface());
if (t == null){
continue;
}
Creature[] crets2 = t.getCreatures();
for (Creature lCret : crets2) {
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)) continue;
if(Server.rand.nextInt(3) == 0){
target = lCret;
break;
}
}
Creature[] undergroundCreatures = getUndergroundCreatures(x, y);
if(undergroundCreatures != null){
for(Creature lCret : undergroundCreatures){
if (lCret.isUnique() || lCret.isInvulnerable() || lCret == titan || isTitanMinion(lCret)) continue;
if(Server.rand.nextInt(3) == 0){
target = lCret;
break;
}
}
}
if(target != null){
break;
}
}
if(target != null){
break;
}
}
// public static Creature doNew(int templateid, float aPosX, float aPosY, float aRot, int layer, String name, byte gender) throws Exception {
Creature minion = Creature.doNew(templateType, tilex, tiley, 360f*Server.rand.nextFloat(), titan.getLayer(), "", (byte)0);
if(target != null){
minion.setOpponent(target);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static HashMap<Creature, Integer> titanDamage = new HashMap<>();
protected static HashMap<Long, Integer> titanAdvancedTimed = new HashMap<>();
protected static void pollTimeMechanics(Creature titan){
int prevDamage = titanDamage.get(titan);
int currentDamage = titan.getStatus().damage;
long wurmid = titan.getWurmId();
if(titan.isOnSurface() && currentDamage > 0){
// Advanced Ability
int chance;
int range;
int radius;
if(currentDamage > 52428) { // 20%
chance = 40;
range = 8;
radius = 2;
}else if(currentDamage > 32767){ // 50%
chance = 45;
range = 5;
radius = 1;
}else if(currentDamage > 16383){ // 75%
chance = 55;
range = 4;
radius = 1;
}else{
chance = 60;
range = 3;
radius = 0;
}
if(titanAdvancedTimed.containsKey(wurmid)){
int currentChance = titanAdvancedTimed.get(wurmid);
boolean success = Server.rand.nextInt(currentChance) == 0;
if(success){
performAdvancedAbility(titan, range, radius);
titanAdvancedTimed.put(wurmid, currentChance+chance-1);
}else{
titanAdvancedTimed.put(wurmid, currentChance-1);
}
}else{
titanAdvancedTimed.put(wurmid, chance);
}
}else if(!titan.isOnSurface() && Server.rand.nextInt(20) == 0){
performAdvancedAbility(titan, 5, 2);
}
}
protected static void pollDamageMechanics(Creature titan){
int prevDamage = titanDamage.get(titan);
int currentDamage = titan.getStatus().damage;
if(currentDamage > 0 && prevDamage == 0){ // First attack
String msg = "<"+titan.getName()+" [100%]> Mere mortals dare to face me?";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
}
if(currentDamage > 8191 && prevDamage < 8191){ // 87.5%
String msg = "<"+titan.getName()+" [88%]> You actually think you can defeat me?";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
}
if(currentDamage > 16383 && prevDamage < 16383){ // 75%
String msg = "<"+titan.getName()+" [75%]> I am not alone.";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
summonMinions(titan, Server.rand.nextInt(2)+2);
}
if(currentDamage > 26214 && prevDamage < 26214){ // 60%
String msg = "<"+titan.getName()+" [60%]> You will feel my wrath!";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
performBasicAbility(titan);
}
if(currentDamage > 32767 && prevDamage < 32767){ // 50%
String msg = "<"+titan.getName()+" [50%]> I've had enough of you. Minions, assemble!";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
summonMinions(titan, Server.rand.nextInt(4)+4);
performBasicAbility(titan);
}
if(currentDamage > 39321 && prevDamage < 39321){ // 40%
String msg = "<"+titan.getName()+" [40%]> Let's try something new, shall we?";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
performAdvancedAbility(titan, 7, 2);
performAdvancedAbility(titan, 7, 2);
}
if(currentDamage > 45874 && prevDamage < 45874){ // 30%
String msg = "<"+titan.getName()+" [30%]> Perhaps minions aren't enough. Now, try my champions!";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
summonChampions(titan, Server.rand.nextInt(2)+2);
performBasicAbility(titan);
}
if(currentDamage > 52428 && prevDamage < 52428){ // 20%
String msg = "<"+titan.getName()+" [20%]> Enough! I will end you!";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
performBasicAbility(titan);
performAdvancedAbility(titan, 5, 3);
}
if(currentDamage > 58981 && prevDamage < 58981){ // 10%
String msg = "<"+titan.getName()+" [10%]> Minions... Champions... Only one way to win a battle: An army!";
MiscChanges.sendGlobalFreedomChat(titan, msg, 255, 105, 180);
MiscChanges.sendServerTabMessage("titan", msg, 255, 105, 180);
Zones.flash(titan.getTileX(), titan.getTileY(), false);
summonMinions(titan, Server.rand.nextInt(5)+7);
summonChampions(titan, Server.rand.nextInt(3)+3);
performBasicAbility(titan);
performAdvancedAbility(titan, 4, 3);
}
if(currentDamage > 16383 && Server.rand.nextInt(10) == 0){
if(currentDamage > 45874){
summonMinions(titan, Server.rand.nextInt(2)+2);
}else if(currentDamage > 32767){
summonMinions(titan, Server.rand.nextInt(3)+1);
}else{
summonMinions(titan, Server.rand.nextInt(2)+1);
}
}
if(currentDamage > 16383 && Server.rand.nextInt(15) == 0){
if(currentDamage > 45874){ // 30%
if(Server.rand.nextInt(10) == 0){
performBasicAbility(titan);
}
}else if(currentDamage > 32767){ // 50%
if(Server.rand.nextInt(12) == 0){
performBasicAbility(titan);
}
}else{ // 75%
if(Server.rand.nextInt(10) == 0){
performBasicAbility(titan);
}
}
}
if(currentDamage > 58981 && Server.rand.nextInt(30) == 0){
summonChampions(titan, 1);
}
titanDamage.put(titan, currentDamage);
}
public static void pollTitan(Creature titan){
if(titanDamage.containsKey(titan)){
int prevDamage = titanDamage.get(titan);
int currentDamage = titan.getStatus().damage;
pollTimeMechanics(titan);
if(currentDamage > prevDamage){
pollDamageMechanics(titan);
}
}else{
titanDamage.put(titan, titan.getStatus().damage);
}
}
public static ArrayList<Creature> titans = new ArrayList<>();
public static long lastPolledTitanSpawn = 0;
public static long lastSpawnedTitan = 0;
public static final long titanRespawnTime = TimeConstants.HOUR_MILLIS*80L;
public static void addTitan(Creature mob){
if(isTitan(mob) && !titans.contains(mob)){
titans.add(mob);
}
}
public static void removeTitan(Creature mob){
if(isTitan(mob)){
titans.remove(mob);
}
}
public static void pollTitanSpawn(){
if(!initializedTitans){
return;
}
Creature[] crets = Creatures.getInstance().getCreatures();
for(Creature c : crets){
if(isTitan(c) && !titans.contains(c)){
titans.add(c);
logger.info("Existing titan identified ("+c.getName()+"). Adding to titan list.");
}
}
/*for(Creature c : titans){
if(c.isDead()){
titans.remove(c);
}
}*/
int i = 0;
while(i < titans.size()){
if(titans.get(i).isDead()){
titans.remove(titans.get(i));
logger.info("Titan was found dead ("+titans.get(i).getName()+"). Removing from titan list.");
}else{
i++;
}
}
if(titans.isEmpty()){
if(lastSpawnedTitan + titanRespawnTime < System.currentTimeMillis()){
logger.info("No Titan was found, and the timer has expired. Spawning a new one.");
boolean found = false;
int spawnX = 2048;
int spawnY = 2048;
while(!found){
int x = Server.rand.nextInt(Server.surfaceMesh.getSize());
int y = Server.rand.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
if(height > 0 && height < 1000 && Creature.getTileSteepness(x, y, true)[1] < 30){
Village v = Villages.getVillage(x, y, true);
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
if(v != null){
break;
}
}
}
if(v != null){
continue;
}
spawnX = x*4;
spawnY = y*4;
found = true;
}
}
/*float worldSizeX = Zones.worldTileSizeX;
float worldSizeY = Zones.worldTileSizeY;
float minX = worldSizeX*0.25f;
float minY = worldSizeY*0.25f;
int tilex = (int) (minX+(minX*2*Server.rand.nextFloat()))*4;
int tiley = (int) (minY+(minY*2*Server.rand.nextFloat()))*4;*/
int[] titanTemplates = {Lilith.templateId, Ifrit.templateId};
try {
Creature.doNew(titanTemplates[Server.rand.nextInt(titanTemplates.length)], spawnX, spawnY, 360f*Server.rand.nextFloat(), 0, "", (byte)0);
lastSpawnedTitan = System.currentTimeMillis();
updateLastSpawnedTitan();
} catch (Exception e) {
logger.severe("Failed to create Titan.");
e.printStackTrace();
}
}
}else{
for(Creature c : titans){
c.healRandomWound(1000);
}
lastPolledTitanSpawn = System.currentTimeMillis();
}
}
public static void pollTitans(){
for(Creature c : titans){
if(isTitan(c)){
pollTitan(c);
}
}
}
public static void preInit(){
try {
ClassPool classPool = HookManager.getInstance().getClassPool();
Class<Titans> thisClass = Titans.class;
String replace;
Util.setReason("Disable natural regeneration on titans.");
CtClass ctWound = classPool.get("com.wurmonline.server.bodys.Wound");
replace = "if(!"+Titans.class.getName()+".isTitan(this.creature)){"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctWound, "poll", "modifySeverity", replace);
Util.instrumentDeclared(thisClass, ctWound, "poll", "checkInfection", replace);
Util.instrumentDeclared(thisClass, ctWound, "poll", "checkPoison", replace);
/*Util.setReason("Disable casting Smite on titans.");
CtClass ctSmite = classPool.get("com.wurmonline.server.spells.Smite");
replace = "if("+Titans.class.getName()+".isTitan($3)){"
+ " $2.getCommunicator().sendNormalServerMessage(\"You cannot smite a Titan!\");"
+ " return false;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctSmite, "precondition", replace);*/
Util.setReason("Disable casting Worm Brains on titans.");
CtClass ctWormBrains = classPool.get("com.wurmonline.server.spells.WormBrains");
replace = "if("+Titans.class.getName()+".isTitan($3)){"
+ " $2.getCommunicator().sendNormalServerMessage(\"Titans are immune to that spell.\");"
+ " return false;"
+ "}";
Util.insertBeforeDeclared(thisClass, ctWormBrains, "precondition", replace);
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
Util.setReason("Add spell resistance to titans.");
replace = "if("+Titans.class.getName()+".isTitan(this)){" +
" return 0.05f;" +
"}";
Util.insertBeforeDeclared(thisClass, ctCreature, "addSpellResistance", replace);
Util.setReason("Increase titan extra damage to pets.");
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);
replace = "if($2.isDominated() && $1 != null && "+Titans.class.getName()+".isTitan($1)){" +
" logger.info(\"Detected titan hit on a pet. Adding damage.\");" +
" $5 = $5 * 2d;" +
"}";
Util.insertBeforeDescribed(thisClass, ctCombatEngine, "addWound", desc1, replace);
}catch (NotFoundException e) {
throw new HookException(e);
}
}
}

View File

@@ -5,22 +5,25 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import com.wurmonline.server.Servers;
import com.wurmonline.server.items.CreationEntry;
import com.wurmonline.server.items.CreationMatrix;
import com.wurmonline.server.items.ItemList;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import org.gotti.wurmunlimited.modloader.interfaces.Configurable;
import org.gotti.wurmunlimited.modloader.interfaces.Initable;
import org.gotti.wurmunlimited.modloader.interfaces.ItemTemplatesCreatedListener;
import org.gotti.wurmunlimited.modloader.interfaces.PreInitable;
import org.gotti.wurmunlimited.modloader.interfaces.ServerPollListener;
import org.gotti.wurmunlimited.modloader.interfaces.ServerStartedListener;
import org.gotti.wurmunlimited.modloader.interfaces.WurmServerMod;
import org.gotti.wurmunlimited.modloader.interfaces.*;
import org.gotti.wurmunlimited.modsupport.ModSupportDb;
import org.gotti.wurmunlimited.modsupport.actions.ModActions;
import org.gotti.wurmunlimited.modsupport.creatures.ModCreatures;
import org.gotti.wurmunlimited.modsupport.vehicles.ModVehicleBehaviours;
@@ -43,13 +46,11 @@ import javassist.expr.MethodCall;
import mod.sin.actions.*;
import mod.sin.creatures.*;
import mod.sin.creatures.titans.*;
import mod.sin.wyvern.arena.Arena;
import mod.sin.wyvern.arena.SupplyDepots;
import mod.sin.wyvern.bestiary.MethodsBestiary;
import mod.sin.wyvern.mastercraft.Mastercraft;
public class WyvernMods
implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCreatedListener, ServerStartedListener, ServerPollListener {
implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCreatedListener, ServerStartedListener, ServerPollListener, PlayerLoginListener {
private static Logger logger = Logger.getLogger(WyvernMods.class.getName());
public static boolean espCounter = false;
public static boolean enableDepots = false;
@@ -119,6 +120,17 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
TreasureChests.preInit();
MiscChanges.preInit();
Arena.preInit();
Titans.preInit();
RareSpawns.preInit();
PlayerTitles.preInit();
TeleportHandler.preInit();
MethodsBestiary.preInit();
MissionCreator.preInit();
CombatChanges.preInit();
MeditationPerks.preInit();
MountedChanges.preInit();
EconomicChanges.preInit();
QualityOfLife.preInit();
AntiCheat.preInit();
Mastercraft.preInit();
Mastercraft.addNewTitles();
@@ -140,7 +152,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
}
});
} catch (CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException((Throwable)e);
throw new HookException(e);
}
}
@@ -157,28 +169,37 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
// Epic:
logger.info("Registering Epic creatures.");
ModCreatures.addCreature(new LavaFiend());
//ModCreatures.addCreature(new SolDemon());
ModCreatures.addCreature(new SolDemon());
ModCreatures.addCreature(new Worg());
// Wyverns:
logger.info("Registering Wyverns.");
ModCreatures.addCreature(new WyvernBlack());
ModCreatures.addCreature(new WyvernGreen());
ModCreatures.addCreature(new WyvernRed());
ModCreatures.addCreature(new WyvernWhite());
ModCreatures.addCreature(new WyvernBlue());
// Flavor Mobs:
logger.info("Registering Flavor creatures.");
ModCreatures.addCreature(new Avenger());
//ModCreatures.addCreature(new Charger());
ModCreatures.addCreature(new ForestSpider());
ModCreatures.addCreature(new Giant());
//ModCreatures.addCreature(new HornedPony());
//ModCreatures.addCreature(new LargeBoar());
ModCreatures.addCreature(new Charger());
ModCreatures.addCreature(new HornedPony());
ModCreatures.addCreature(new LargeBoar());
ModCreatures.addCreature(new SpiritTroll());
// Event Mobs:
logger.info("Registering Event creatures.");
ModCreatures.addCreature(new IceCat());
ModCreatures.addCreature(new FireCrab());
ModCreatures.addCreature(new FireGiant());
// Bosses:
logger.info("Registering Custom Boss creatures.");
//ModCreatures.addCreature(new Reaper());
//ModCreatures.addCreature(new SpectralDrake());
ModCreatures.addCreature(new Reaper());
ModCreatures.addCreature(new SpectralDrake());
// Uniques:
ModCreatures.addCreature(new Facebreyker());
@@ -195,6 +216,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
logger.info("Registering Custom NPC creatures.");
//ModCreatures.addCreature(new RobZombie());
//ModCreatures.addCreature(new MacroSlayer());
ModCreatures.addCreature(new Terror());
Bounty.init();
@@ -217,6 +239,67 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
}
}
@Override
public void onPlayerLogin(Player p) {
Connection dbcon;
PreparedStatement ps;
boolean foundLeaderboardOpt = false;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM LeaderboardOpt");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (!rs.getString("name").equals(p.getName())) continue;
foundLeaderboardOpt = true;
}
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
if (!foundLeaderboardOpt) {
logger.info("No leaderboard entry for "+p.getName()+". Creating one.");
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("INSERT INTO LeaderboardOpt (name) VALUES(\"" + p.getName() + "\")");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
boolean foundPlayerStats = false;
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("SELECT * FROM PlayerStats");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (!rs.getString("NAME").equals(p.getName())) continue;
foundPlayerStats = true;
}
rs.close();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
if (!foundPlayerStats) {
logger.info("No player stats entry for "+p.getName()+". Creating one.");
try {
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("INSERT INTO PlayerStats (NAME) VALUES(\"" + p.getName() + "\")");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
PlayerTitles.awardCustomTitles(p);
}
@Override
public void onServerStarted() {
try {
@@ -231,13 +314,17 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
logger.info("Registering Custom actions.");
ModActions.registerAction(new UnequipAllAction());
ModActions.registerAction(new ReceiveMailAction());
ModActions.registerAction(new LeaderboardAction());
logger.info("Registering Arena actions.");
ModActions.registerAction(new SorceryCombineAction());
//ModActions.registerAction(new VillageTeleportAction()); // [3/28/18] Disabled - Highway Portals added instead.
ModActions.registerAction(new ArenaTeleportAction());
ModActions.registerAction(new ArenaEscapeAction());
logger.info("Registering Dev actions.");
ModActions.registerAction(new MissionAction());
logger.info("Setting custom creature corpse models.");
MethodsBestiary.setTemplateVariables();
if(Deities.getDeity(101) != null){ // Edit Breyk player god
/*if(Deities.getDeity(101) != null){ // Edit Breyk player god
Deity breyk = Deities.getDeity(101);
// Add some defining affinities
breyk.repairer = true;
@@ -248,8 +335,8 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
breyk.warrior = false;
breyk.healer = false;
breyk.clayAffinity = false;
}
if(Deities.getDeity(102) != null){ // Edit Cyberhusky player god
}*/
/*if(Deities.getDeity(102) != null){ // Edit Cyberhusky player god
Deity cyberhusky = Deities.getDeity(102);
// Add some defining affinities
cyberhusky.hateGod = true;
@@ -258,7 +345,7 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
// Remove some affinities
cyberhusky.woodAffinity = false;
cyberhusky.befriendCreature = false;
}
}*/
//espCounter = Servers.localServer.PVPSERVER; // Enables on PvP server by default.
//espCounter = false;
@@ -270,21 +357,102 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
logger.info("Failed to set tickTime for stealing!");
e.printStackTrace();
}
SkillTemplate meditating = SkillSystem.templates.get(SkillList.MEDITATING);
try {
ReflectionUtil.setPrivateField(meditating, ReflectionUtil.getField(meditating.getClass(), "tickTime"), TimeConstants.HOUR_MILLIS);
} catch (IllegalAccessException | NoSuchFieldException e) {
logger.info("Failed to set tickTime for meditating!");
e.printStackTrace();
}
meditating.setDifficulty(300f);
CreationEntry lockpicks = CreationMatrix.getInstance().getCreationEntry(ItemList.lockpick);
try {
ReflectionUtil.setPrivateField(lockpicks, ReflectionUtil.getField(lockpicks.getClass(), "hasMinimumSkillRequirement"), false);
ReflectionUtil.setPrivateField(lockpicks, ReflectionUtil.getField(lockpicks.getClass(), "minimumSkill"), 0.0);
} catch (IllegalAccessException | NoSuchFieldException e) {
logger.info("Failed to set lockpick creation entry changes!");
e.printStackTrace();
}
// Set mining difficulty down to be equivalent to digging.
SkillTemplate mining = SkillSystem.templates.get(SkillList.MINING);
mining.setDifficulty(3000f);
// Triple lockpicking skill
SkillTemplate lockpicking = SkillSystem.templates.get(SkillList.LOCKPICKING);
lockpicking.setDifficulty(700f);
} catch (IllegalArgumentException | ClassCastException e) {
e.printStackTrace();
}
try {
Connection con = ModSupportDb.getModSupportDb();
String sql;
if (!ModSupportDb.hasTable(con, "LeaderboardOpt")) {
sql = "CREATE TABLE LeaderboardOpt (\t\tname\t\t\t\tVARCHAR(30)\t\t\tNOT NULL DEFAULT 'Unknown',\t\tOPTIN\t\t\t\t\tINT\t\tNOT NULL DEFAULT 0)";
PreparedStatement ps = con.prepareStatement(sql);
ps.execute();
ps.close();
}
if (!ModSupportDb.hasTable(con, "SteamIdMap")) {
sql = "CREATE TABLE SteamIdMap (\t\tNAME\t\t\t\tVARCHAR(30)\t\t\tNOT NULL DEFAULT 'Unknown',\t\tSTEAMID\t\t\t\t\tLONG\t\tNOT NULL DEFAULT 0)";
PreparedStatement ps = con.prepareStatement(sql);
ps.execute();
ps.close();
}
if (!ModSupportDb.hasTable(con, "PlayerStats")) {
sql = "CREATE TABLE PlayerStats (NAME VARCHAR(30) NOT NULL DEFAULT 'Unknown', KILLS INT NOT NULL DEFAULT 0, DEATHS INT NOT NULL DEFAULT 0, DEPOTS INT NOT NULL DEFAULT 0, HOTAS INT NOT NULL DEFAULT 0, TITANS INT NOT NULL DEFAULT 0)";
PreparedStatement ps = con.prepareStatement(sql);
ps.execute();
ps.close();
}
if (!ModSupportDb.hasTable(con, "ObjectiveTimers")) {
sql = "CREATE TABLE ObjectiveTimers (\t\tID\t\t\t\tVARCHAR(30)\t\t\tNOT NULL DEFAULT 'Unknown',\t\tTIMER\t\t\t\t\tLONG\t\tNOT NULL DEFAULT 0)";
PreparedStatement ps = con.prepareStatement(sql);
ps.execute();
ps.close();
try {
Connection dbcon;
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("INSERT INTO ObjectiveTimers (ID, TIMER) VALUES(\"DEPOT\", 0)");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
try {
Connection dbcon;
dbcon = ModSupportDb.getModSupportDb();
ps = dbcon.prepareStatement("INSERT INTO ObjectiveTimers (ID, TIMER) VALUES(\"TITAN\", 0)");
ps.executeUpdate();
ps.close();
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}else{
SupplyDepots.initializeDepotTimer();
Titans.initializeTitanTimer();
}
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static long lastSecondPolled = 0;
public static long lastPolledTitanSpawn = 0;
public static final long pollTitanSpawnTime = TimeConstants.MINUTE_MILLIS*10;
public static final long pollTitanSpawnTime = TimeConstants.MINUTE_MILLIS*2;
public static long lastPolledTitans = 0;
public static final long pollTitanTime = TimeConstants.SECOND_MILLIS;
public static long lastPolledDepots = 0;
public static final long pollDepotTime = TimeConstants.MINUTE_MILLIS;
public static long lastPolledRareSpawns = 0;
public static final long pollRareSpawnTime = TimeConstants.MINUTE_MILLIS*5;
public static long lastPolledEternalReservoirs = 0;
public static final long pollEternalReservoirTime = TimeConstants.MINUTE_MILLIS*10;
public static long lastPolledMissionCreator = 0;
public static final long pollMissionCreatorTime = TimeConstants.HOUR_MILLIS*4;
@Override
public void onServerPoll() {
if((lastSecondPolled + TimeConstants.SECOND_MILLIS) < System.currentTimeMillis()){
@@ -293,17 +461,25 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
lastPolledDepots += pollDepotTime;
}
if(lastPolledTitanSpawn + pollTitanSpawnTime < System.currentTimeMillis()){
Arena.pollTitanSpawn();
Titans.pollTitanSpawn();
lastPolledTitanSpawn += pollTitanSpawnTime;
}
if(lastPolledTitans + pollTitanTime < System.currentTimeMillis()){
Arena.pollTitans();
Titans.pollTitans();
lastPolledTitans += pollTitanTime;
}
if(lastPolledRareSpawns + pollRareSpawnTime < System.currentTimeMillis()){
RareSpawns.pollRareSpawns();
lastPolledRareSpawns += pollRareSpawnTime;
}
if(lastPolledEternalReservoirs + pollEternalReservoirTime < System.currentTimeMillis()){
Soulstealing.pollSoulForges();
lastPolledEternalReservoirs += pollEternalReservoirTime;
}
if(lastPolledMissionCreator + pollMissionCreatorTime < System.currentTimeMillis()){
MissionCreator.pollMissions();
lastPolledMissionCreator += pollMissionCreatorTime;
}
// Update counter
if(lastSecondPolled + TimeConstants.SECOND_MILLIS*10 > System.currentTimeMillis()){
@@ -314,7 +490,9 @@ implements WurmServerMod, Configurable, PreInitable, Initable, ItemTemplatesCrea
lastPolledTitanSpawn = System.currentTimeMillis();
lastPolledTitans = System.currentTimeMillis();
lastPolledDepots = System.currentTimeMillis();
lastPolledRareSpawns = System.currentTimeMillis();
lastPolledEternalReservoirs = System.currentTimeMillis();
lastPolledMissionCreator = System.currentTimeMillis();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,22 +3,26 @@ package mod.sin.wyvern.bestiary;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Logger;
import com.wurmonline.mesh.Tiles;
import com.wurmonline.server.creatures.*;
import com.wurmonline.server.items.*;
import com.wurmonline.server.zones.NoSuchZoneException;
import com.wurmonline.server.zones.Zone;
import com.wurmonline.server.zones.Zones;
import com.wurmonline.shared.constants.BodyPartConstants;
import javassist.*;
import javassist.bytecode.Descriptor;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
import mod.sin.items.SealedMap;
import mod.sin.lib.Util;
import mod.sin.wyvern.RareSpawns;
import mod.sin.wyvern.Titans;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import com.wurmonline.server.FailedException;
import com.wurmonline.server.Server;
import com.wurmonline.server.combat.Archery;
import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.CreatureStatus;
import com.wurmonline.server.creatures.CreatureTemplate;
import com.wurmonline.server.creatures.CreatureTemplateFactory;
import com.wurmonline.server.creatures.NoSuchCreatureTemplateException;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemFactory;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.ItemSpellEffects;
import com.wurmonline.server.items.Materials;
import com.wurmonline.server.items.NoSuchTemplateException;
import com.wurmonline.server.skills.SkillList;
import com.wurmonline.server.skills.Skills;
import com.wurmonline.server.skills.SkillsFactory;
@@ -30,7 +34,9 @@ import mod.sin.creatures.titans.*;
import mod.sin.weapons.Club;
import mod.sin.weapons.titan.*;
import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.arena.Arena;
import mod.sin.wyvern.Arena;
import org.gotti.wurmunlimited.modloader.classhooks.HookException;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
public class MethodsBestiary {
protected static Logger logger = Logger.getLogger(MethodsBestiary.class.getName());
@@ -40,9 +46,9 @@ public class MethodsBestiary {
int templateId = template.getTemplateId();
if(templateId == Lilith.templateId){
return true;
}else if(templateId == ForestSpider.templateId){
}/*else if(templateId == ForestSpider.templateId){
return true;
}else if(templateId == Avenger.templateId){
}*/else if(templateId == Avenger.templateId){
return true;
}else if(templateId == HornedPony.templateId){
return true;
@@ -58,9 +64,9 @@ public class MethodsBestiary {
public static byte getCreatureColorRed(CreatureTemplate template){
try {
int templateId = template.getTemplateId();
if(templateId == ForestSpider.templateId){
/*if(templateId == ForestSpider.templateId){
return (byte)0;
}else if(templateId == Avenger.templateId){
}else */if(templateId == Avenger.templateId){
return (byte)70;
}
} catch (IllegalArgumentException | ClassCastException e) {
@@ -92,9 +98,9 @@ public class MethodsBestiary {
int templateId = template.getTemplateId();
if(templateId == Lilith.templateId){
return (byte)0;
}else if(templateId == ForestSpider.templateId){
}/*else if(templateId == ForestSpider.templateId){
return (byte)0;
}else if(templateId == HornedPony.templateId){
}*/else if(templateId == HornedPony.templateId){
return (byte)70;
}else if(templateId == LilithZombie.templateId){
return (byte)0;
@@ -163,10 +169,12 @@ public class MethodsBestiary {
floatToRet *= 0.6f;
}else if(templateId == WyvernWhite.templateId){
floatToRet *= 0.6f;
}else if(templateId == WyvernBlue.templateId){
floatToRet *= 0.6f;
}else if(templateId == MacroSlayer.templateId){
floatToRet *= 1.5f;
}else if(templateId == ForestSpider.templateId){
floatToRet *= 0.4f;
floatToRet *= 0.7f;
}else if(templateId == Avenger.templateId){
floatToRet *= 0.35f;
}else if(templateId == LargeBoar.templateId){
@@ -178,7 +186,9 @@ public class MethodsBestiary {
}else if(templateId == LilithZombie.templateId){
floatToRet *= 0.75f;
}else if(templateId == Charger.templateId){
floatToRet *= 1.5f;
floatToRet *= 1.15f;
}else if(templateId == Terror.templateId){
floatToRet *= 3.0f;
}
return floatToRet * ageSizeModifier;
@@ -200,7 +210,7 @@ public class MethodsBestiary {
}
if(templateId == MaartensMight.templateId){
effs.addSpellEffect(new SpellEffect(titanWeapon.getWurmId(), Enchants.BUFF_NIMBLENESS, 250, 20000000));
effs.addSpellEffect(new SpellEffect(titanWeapon.getWurmId(), (byte) 111, 200, 20000000)); // Phasing
//effs.addSpellEffect(new SpellEffect(titanWeapon.getWurmId(), (byte) 111, 200, 20000000)); // Phasing
}else if(templateId == RaffehsRage.templateId){
effs.addSpellEffect(new SpellEffect(titanWeapon.getWurmId(), Enchants.BUFF_FLAMING_AURA, 150, 20000000));
effs.addSpellEffect(new SpellEffect(titanWeapon.getWurmId(), Enchants.BUFF_FROSTBRAND, 150, 20000000));
@@ -215,14 +225,89 @@ public class MethodsBestiary {
return titanWeapon;
}
} catch (FailedException | NoSuchTemplateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void checkEnchantedBreed(Creature creature){
int tile = Server.surfaceMesh.getTile(creature.getTileX(), creature.getTileY());
byte type = Tiles.decodeType(tile);
if (type == Tiles.Tile.TILE_ENCHANTED_GRASS.id){
logger.info("Creature "+creature.getName()+" was born on enchanted grass, and has a negative trait removed!");
Server.getInstance().broadCastAction(creature.getName()+" was born on enchanted grass, and feels more healthy!", creature, 10);
creature.removeRandomNegativeTrait();
}
}
public static boolean shouldBreedName(Creature creature){
if(creature.getTemplate().getTemplateId() == WyvernBlack.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernGreen.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernRed.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == WyvernWhite.templateId){
return true;
}else if(creature.getTemplate().getTemplateId() == Charger.templateId){
return true;
}
return creature.isHorse();
}
public static boolean isGhostCorpse(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == Avenger.templateId){
return true;
}else if(templateId == SpiritTroll.templateId){
return true;
}else if(templateId == Charger.templateId){
return true;
}
return false;
}
public static float getCustomSpellResistance(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == Avenger.templateId){
return 0.5f;
}else if(templateId == Charger.templateId){
return 1.4f;
}else if(templateId == Giant.templateId){
return 0.3f;
}else if(templateId == LargeBoar.templateId){
return 0.8f;
}else if(templateId == Reaper.templateId){
return 0.1f;
}else if(templateId == SpectralDrake.templateId){
return 0.1f;
}else if(templateId == SpiritTroll.templateId){
return 0.2f;
}else if(templateId == WyvernBlack.templateId){
return 0.4f;
}else if(templateId == WyvernGreen.templateId){
return 0.6f;
}else if(templateId == WyvernWhite.templateId){
return 0.5f;
}else if(templateId == WyvernRed.templateId){
return 0.25f;
}
return -1f;
}
public static boolean isSacrificeImmune(Creature creature){
if(Titans.isTitan(creature) || Titans.isTitanMinion(creature)){
return true;
}else if(RareSpawns.isRareCreature(creature)){
return true;
}else if(creature.isUnique()){
return true;
}
return false;
}
public static boolean isArcheryImmune(Creature performer, Creature defender){
if(Arena.isTitan(defender) || Arena.isTitanMinion(defender)){
if(Titans.isTitan(defender) || Titans.isTitanMinion(defender)){
performer.getCommunicator().sendCombatNormalMessage("You cannot archer "+defender.getName()+", as it is protected by a Titan.");
return true;
}
@@ -237,9 +322,9 @@ public class MethodsBestiary {
if(defender.isRegenerating() && arrow.getTemplateId() == ItemList.arrowShaft){
message = "The "+defender.getName()+" would be unaffected by the "+arrow.getName()+".";
immune = true;
}else if(defender.getTemplate().isNotRebirthable()){
}/*else if(defender.getTemplate().isNotRebirthable()){
immune = true;
}else if(defender.isUnique()){
}*/else if(defender.isUnique()){
immune = true;
}
if(immune){
@@ -248,21 +333,101 @@ public class MethodsBestiary {
return immune;
}
public static boolean blockSkillFrom(Creature defender, Creature attacker){
if(defender == null || attacker == null){
return false;
}
if(defender.isPlayer() && defender.getTarget() != attacker){
return true;
}
try {
if(defender.isPlayer() && attacker.getArmour(BodyPartConstants.TORSO) != null){
return true;
}
} catch (NoArmourException | NoSpaceException e) {
e.printStackTrace();
}
return false;
}
public static boolean denyPathingOverride(Creature creature){
if(creature.getTemplate().getTemplateId() == Charger.templateId){
return true;
}
return false;
}
public static boolean hasCustomCorpseSize(Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == Avenger.templateId){
return true;
}else{
return Titans.isTitan(creature);
}
}
public static void setCorpseSizes(Creature creature, Item corpse){
if(corpse.getTemplateId() != ItemList.corpse){
return;
}
int templateId = creature.getTemplate().getTemplateId();
boolean sendStatus = false;
int size = 50000;
if(templateId == Avenger.templateId){
size *= 1.2;
corpse.setSizes(size);
sendStatus = true;
}else if(Titans.isTitan(creature)){
size *= 1.5;
corpse.setSizes(size);
sendStatus = true;
}else{
corpse.setSizes((int)((float)(corpse.getSizeX() * (creature.getSizeModX() & 255)) / 64.0f), (int)((float)(corpse.getSizeY() * (creature.getSizeModY() & 255)) / 64.0f), (int)((float)(corpse.getSizeZ() * (creature.getSizeModZ() & 255)) / 64.0f));
}
if(sendStatus){
try {
Zone zone = Zones.getZone((int)corpse.getPosX() >> 2, (int)corpse.getPosY() >> 2, corpse.isOnSurface());
zone.removeItem(corpse, true, true);
zone.addItem(corpse, true, false, false);
} catch (NoSuchZoneException e) {
e.printStackTrace();
}
}
}
public static byte newCreatureType(int templateid, byte ctype) throws Exception{
CreatureTemplate template = CreatureTemplateFactory.getInstance().getTemplate(templateid);
if(ctype == 0 && (template.isAggHuman() || template.getBaseCombatRating() > 10) && !template.isUnique() && !Titans.isTitan(templateid)){
if(Server.rand.nextInt(5) == 0){
ctype = (byte) (Server.rand.nextInt(11)+1);
if(Server.rand.nextInt(50) == 0){
ctype = 99;
}
}
}
return ctype;
}
public static void modifyNewCreature(Creature creature){
try{
if(Arena.isTitan(creature)){
Arena.addTitan(creature);
MiscChanges.sendGlobalFreedomChat(creature, "The titan "+creature.getName()+" has stepped into the mortal realm. Challenge "+creature.getHimHerItString()+" in the Arena if you dare.", 255, 105, 180);
if(creature.getTemplate().getTemplateId() == Lilith.templateId){
if(Titans.isTitan(creature)){
Titans.addTitan(creature);
MiscChanges.sendGlobalFreedomChat(creature, "The titan "+creature.getName()+" has stepped into the mortal realm. Challenge them if you dare.", 255, 105, 180);
/*if(creature.getTemplate().getTemplateId() == Lilith.templateId){
Item titanWeapon = createNewTitanWeapon(creature.getName(), new int[]{VindictivesVengeance.templateId, WilhelmsWrath.templateId});
creature.getInventory().insertItem(titanWeapon);
}else if(creature.getTemplate().getTemplateId() == Ifrit.templateId){
Item titanWeapon = createNewTitanWeapon(creature.getName(), new int[]{MaartensMight.templateId, RaffehsRage.templateId});
creature.getInventory().insertItem(titanWeapon);
}
}*/
Titans.addTitanLoot(creature);
}else if(creature.getTemplate().getTemplateId() == Facebreyker.templateId){
Item club = ItemFactory.createItem(Club.templateId, 80f+(Server.rand.nextFloat()*15f), Server.rand.nextBoolean() ? Materials.MATERIAL_GLIMMERSTEEL : Materials.MATERIAL_ADAMANTINE, Server.rand.nextBoolean() ? (byte) 1 : (byte) 2, "Facebreyker");
Item club = ItemFactory.createItem(Club.templateId, 80f+(Server.rand.nextFloat()*15f), Server.rand.nextBoolean() ? Materials.MATERIAL_GLIMMERSTEEL : Materials.MATERIAL_ADAMANTINE, Server.rand.nextBoolean() ? (byte) 0 : (byte) 1, "Facebreyker");
creature.getInventory().insertItem(club);
} else if(RareSpawns.isRareCreature(creature)){
MiscChanges.sendServerTabMessage("event", "A rare "+creature.getName()+" has surfaced.", 123, 104, 238);
Item sealedMap = ItemFactory.createItem(SealedMap.templateId, 60f+(30f*Server.rand.nextFloat()), creature.getName());
creature.getInventory().insertItem(sealedMap, true);
}
}catch(Exception e){
e.printStackTrace();
@@ -302,6 +467,17 @@ public class MethodsBestiary {
}
}
private static void setNoCorpse(int templateId){
try{
CreatureTemplate template = CreatureTemplateFactory.getInstance().getTemplate(templateId);
if(template != null){
ReflectionUtil.setPrivateField(template, ReflectionUtil.getField(template.getClass(), "noCorpse"), true);
}
} catch (NoSuchCreatureTemplateException | IllegalArgumentException | IllegalAccessException | ClassCastException | NoSuchFieldException e) {
e.printStackTrace();
}
}
private static void setGrazer(int templateId){
try{
CreatureTemplate template = CreatureTemplateFactory.getInstance().getTemplate(templateId);
@@ -343,120 +519,51 @@ public class MethodsBestiary {
setCorpseModel(Avenger.templateId, "fogspider.");
setCorpseModel(SpiritTroll.templateId, "fogspider.");
setCorpseModel(SpectralDrake.templateId, "fogspider.");
/*CreatureTemplate spectralDrake = CreatureTemplateFactory.getInstance().getTemplate(SpectralDrake.templateId);
if(spectralDrake != null){
ReflectionUtil.setPrivateField(spectralDrake, ReflectionUtil.getField(spectralDrake.getClass(), "corpsename"), "fogspider.");
}*/
setCorpseModel(Charger.templateId, "fogspider.");
// Non-fog spider models
setCorpseModel(WyvernBlack.templateId, "blackdragonhatchling.");
/*CreatureTemplate blackWyvern = CreatureTemplateFactory.getInstance().getTemplate(WyvernBlack.templateId);
if(blackWyvern != null){
ReflectionUtil.setPrivateField(blackWyvern, ReflectionUtil.getField(blackWyvern.getClass(), "corpsename"), "blackdragonhatchling.");
}*/
setCorpseModel(WyvernGreen.templateId, "greendragonhatchling.");
/*CreatureTemplate greenWyvern = CreatureTemplateFactory.getInstance().getTemplate(WyvernGreen.templateId);
if(greenWyvern != null){
ReflectionUtil.setPrivateField(greenWyvern, ReflectionUtil.getField(greenWyvern.getClass(), "corpsename"), "greendragonhatchling.");
}*/
setCorpseModel(WyvernRed.templateId, "reddragonhatchling.");
/*CreatureTemplate redWyvern = CreatureTemplateFactory.getInstance().getTemplate(WyvernRed.templateId);
if(redWyvern != null){
ReflectionUtil.setPrivateField(redWyvern, ReflectionUtil.getField(redWyvern.getClass(), "corpsename"), "reddragonhatchling.");
}*/
setCorpseModel(WyvernWhite.templateId, "whitedragonhatchling.");
/*CreatureTemplate whiteWyvern = CreatureTemplateFactory.getInstance().getTemplate(WyvernWhite.templateId);
if(whiteWyvern != null){
ReflectionUtil.setPrivateField(whiteWyvern, ReflectionUtil.getField(whiteWyvern.getClass(), "corpsename"), "whitedragonhatchling.");
}*/
setCorpseModel(WyvernBlue.templateId, "bluedragonhatchling.");
setCorpseModel(Facebreyker.templateId, "riftogre.");
/*CreatureTemplate facebreyker = CreatureTemplateFactory.getInstance().getTemplate(Facebreyker.templateId);
if(facebreyker != null){
ReflectionUtil.setPrivateField(facebreyker, ReflectionUtil.getField(facebreyker.getClass(), "corpsename"), "riftogre.");
}*/
setCorpseModel(ForestSpider.templateId, "hugespider.");
/*CreatureTemplate forestSpider = CreatureTemplateFactory.getInstance().getTemplate(ForestSpider.templateId);
if(forestSpider != null){
ReflectionUtil.setPrivateField(forestSpider, ReflectionUtil.getField(forestSpider.getClass(), "corpsename"), "hugespider.");
}*/
setCorpseModel(ForestSpider.templateId, "fogspider.");
setCorpseModel(Giant.templateId, "forestgiant.");
/*CreatureTemplate giant = CreatureTemplateFactory.getInstance().getTemplate(Giant.templateId);
if(giant != null){
ReflectionUtil.setPrivateField(giant, ReflectionUtil.getField(giant.getClass(), "corpsename"), "forestgiant.");
}*/
setCorpseModel(LargeBoar.templateId, "wildboar.");
/*CreatureTemplate largeBoar = CreatureTemplateFactory.getInstance().getTemplate(LargeBoar.templateId);
if(largeBoar != null){
ReflectionUtil.setPrivateField(largeBoar, ReflectionUtil.getField(largeBoar.getClass(), "corpsename"), "wildboar.");
}*/
setCorpseModel(HornedPony.templateId, "unicorn.");
/*CreatureTemplate hornedPony = CreatureTemplateFactory.getInstance().getTemplate(HornedPony.templateId);
if(hornedPony != null){
ReflectionUtil.setPrivateField(hornedPony, ReflectionUtil.getField(hornedPony.getClass(), "corpsename"), "unicorn.");
}*/
setCorpseModel(IfritSpider.templateId, "lavaspider.");
/*CreatureTemplate ifritSpider = CreatureTemplateFactory.getInstance().getTemplate(IfritSpider.templateId);
if(ifritSpider != null){
ReflectionUtil.setPrivateField(ifritSpider, ReflectionUtil.getField(ifritSpider.getClass(), "corpsename"), "lavaspider.");
}*/
setCorpseModel(IfritFiend.templateId, "lavafiend.");
/*CreatureTemplate ifritFiend = CreatureTemplateFactory.getInstance().getTemplate(IfritFiend.templateId);
if(ifritFiend != null){
ReflectionUtil.setPrivateField(ifritFiend, ReflectionUtil.getField(ifritFiend.getClass(), "corpsename"), "lavafiend.");
}*/
// Also apply the ghost modifier
setGhost(SpiritTroll.templateId);
setGhost(Avenger.templateId);
setGhost(LilithWraith.templateId);
setGhost(Charger.templateId);
/*CreatureTemplate spiritTroll = CreatureTemplateFactory.getInstance().getTemplate(SpiritTroll.templateId);
if(spiritTroll != null){
ReflectionUtil.setPrivateField(spiritTroll, ReflectionUtil.getField(spiritTroll.getClass(), "ghost"), true);
}
CreatureTemplate avenger = CreatureTemplateFactory.getInstance().getTemplate(Avenger.templateId);
if(avenger != null){
ReflectionUtil.setPrivateField(avenger, ReflectionUtil.getField(avenger.getClass(), "ghost"), true);
}
CreatureTemplate lilithWight = CreatureTemplateFactory.getInstance().getTemplate(LilithWraith.templateId);
if(lilithWight != null){
ReflectionUtil.setPrivateField(lilithWight, ReflectionUtil.getField(lilithWight.getClass(), "ghost"), true);
}
CreatureTemplate charger = CreatureTemplateFactory.getInstance().getTemplate(Charger.templateId);
if(charger != null){
ReflectionUtil.setPrivateField(charger, ReflectionUtil.getField(charger.getClass(), "ghost"), true);
}*/
// Dragon natural armour increases:
setNaturalArmour(CreatureTemplate.DRAGON_BLUE_CID, 0.04f);
/*CreatureTemplate dragonBlue = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAGON_BLUE_CID);
ReflectionUtil.setPrivateField(dragonBlue, ReflectionUtil.getField(dragonBlue.getClass(), "naturalArmour"), 0.05f);*/
setNaturalArmour(CreatureTemplate.DRAGON_WHITE_CID, 0.04f);
/*CreatureTemplate dragonGreen = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAGON_WHITE_CID);
ReflectionUtil.setPrivateField(dragonGreen, ReflectionUtil.getField(dragonGreen.getClass(), "naturalArmour"), 0.05f);*/
setNaturalArmour(CreatureTemplate.DRAGON_BLACK_CID, 0.055f);
/*CreatureTemplate dragonBlack = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAGON_BLACK_CID);
ReflectionUtil.setPrivateField(dragonBlack, ReflectionUtil.getField(dragonBlack.getClass(), "naturalArmour"), 0.07f);*/
setNaturalArmour(CreatureTemplate.DRAGON_WHITE_CID, 0.04f);
/*CreatureTemplate dragonWhite = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAGON_WHITE_CID);
ReflectionUtil.setPrivateField(dragonWhite, ReflectionUtil.getField(dragonWhite.getClass(), "naturalArmour"), 0.05f);*/
setNaturalArmour(CreatureTemplate.DRAGON_BLUE_CID, 0.035f);
setNaturalArmour(CreatureTemplate.DRAGON_WHITE_CID, 0.035f);
setNaturalArmour(CreatureTemplate.DRAGON_BLACK_CID, 0.045f);
setNaturalArmour(CreatureTemplate.DRAGON_WHITE_CID, 0.035f);
// Drake natural armour increases:
setNaturalArmour(CreatureTemplate.DRAKE_RED_CID, 0.075f);
/*CreatureTemplate drakeRed = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAKE_RED_CID);
ReflectionUtil.setPrivateField(drakeRed, ReflectionUtil.getField(drakeRed.getClass(), "naturalArmour"), 0.085f);*/
setNaturalArmour(CreatureTemplate.DRAKE_BLUE_CID, 0.075f);
/*CreatureTemplate drakeBlue = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAKE_BLUE_CID);
ReflectionUtil.setPrivateField(drakeBlue, ReflectionUtil.getField(drakeBlue.getClass(), "naturalArmour"), 0.085f);*/
setNaturalArmour(CreatureTemplate.DRAKE_WHITE_CID, 0.085f);
/*CreatureTemplate drakeWhite = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAKE_WHITE_CID);
ReflectionUtil.setPrivateField(drakeWhite, ReflectionUtil.getField(drakeWhite.getClass(), "naturalArmour"), 0.1f);*/
setNaturalArmour(CreatureTemplate.DRAKE_GREEN_CID, 0.075f);
/*CreatureTemplate drakeGreen = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAKE_GREEN_CID);
ReflectionUtil.setPrivateField(drakeGreen, ReflectionUtil.getField(drakeGreen.getClass(), "naturalArmour"), 0.085f);*/
setNaturalArmour(CreatureTemplate.DRAKE_BLACK_CID, 0.065f);
/*CreatureTemplate drakeBlack = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.DRAKE_BLACK_CID);
ReflectionUtil.setPrivateField(drakeBlack, ReflectionUtil.getField(drakeBlack.getClass(), "naturalArmour"), 0.065f);*/
setNaturalArmour(CreatureTemplate.DRAKE_RED_CID, 0.065f);
setNaturalArmour(CreatureTemplate.DRAKE_BLUE_CID, 0.065f);
setNaturalArmour(CreatureTemplate.DRAKE_WHITE_CID, 0.075f);
setNaturalArmour(CreatureTemplate.DRAKE_GREEN_CID, 0.065f);
setNaturalArmour(CreatureTemplate.DRAKE_BLACK_CID, 0.055f);
// Goblin leader natural armour increase:
setNaturalArmour(CreatureTemplate.GOBLIN_LEADER_CID, 0.075f);
/*CreatureTemplate goblinLeader = CreatureTemplateFactory.getInstance().getTemplate(CreatureTemplate.GOBLIN_LEADER_CID);
ReflectionUtil.setPrivateField(goblinLeader, ReflectionUtil.getField(goblinLeader.getClass(), "naturalArmour"), 0.085f);*/
setNaturalArmour(CreatureTemplate.GOBLIN_LEADER_CID, 0.055f);
// Make titan minions drop no corpse
setNoCorpse(IfritFiend.templateId);
setNoCorpse(IfritSpider.templateId);
setNoCorpse(LilithWraith.templateId);
setNoCorpse(LilithZombie.templateId);
setNoCorpse(IceCat.templateId);
setNoCorpse(FireCrab.templateId);
setNoCorpse(FireGiant.templateId);
setNoCorpse(Terror.templateId);
// Set hens and roosters as grazers
setGrazer(CreatureTemplate.HEN_CID);
@@ -467,4 +574,211 @@ public class MethodsBestiary {
// Set worg fields
setWorgFields(CreatureTemplate.WORG_CID);
}
protected static void sendParticleEffect(Communicator comm, long creatureId, Creature creature, String particle, float duration){
comm.sendAddEffect(creatureId, (short) 27, creature.getPosX(), creature.getPosY(), creature.getPositionZ(), (byte) creature.getLayer(), particle, duration, 0);
}
protected static void sendAddEffect(Communicator comm, long creatureId, byte effectNum){
comm.sendAttachEffect(creatureId, effectNum, (byte) 1, (byte) -1, (byte) -1, (byte) 1);
}
// - Good Effects -
// rift01 [large], rift02 [small]
// treasureP [light bubbles]
// spawneffect2 [sparkle fireworks]
// reindeer [light sparkles]
// iceBall_1_1 [clean ice effect]
// acidBall_1_1 [clean green ball effect]
// - Bad Effects -
// spawneffect [sparkle eye cancer]
// snow1emitter [disappears instantly}, snow2emitter [disappears instantly]
// spawneffectshort [disappears instantly]
// iceWispSpark [tiny and unnoticeable]
// iceBolt1 [very flickery]
// iceTail1 [small and points downwards]
// acidWispSpark [basically invisible]
// acidTail1 [inconsistent trail]
// acidBolt1 [very flickery]
// lightningTail1 [weird effect]
public static void addCreatureSpecialEffect(long creatureId, Communicator comm, Creature creature){
int templateId = creature.getTemplate().getTemplateId();
if(templateId == IceCat.templateId){
String particle = "iceBall_1_1";
sendParticleEffect(comm, creatureId, creature, particle, Float.MAX_VALUE);
}else if(templateId == FireCrab.templateId){
sendAddEffect(comm, creatureId, (byte) 1);
}else if(templateId == FireGiant.templateId){
sendAddEffect(comm, creatureId, (byte) 1);
}
}
public static void preInit(){
try{
ClassPool classPool = HookManager.getInstance().getClassPool();
final Class<MethodsBestiary> thisClass = MethodsBestiary.class;
String replace;
Util.setReason("Disable sacrificing strong creatures.");
CtClass ctCreature = classPool.get("com.wurmonline.server.creatures.Creature");
CtClass ctItem = classPool.get("com.wurmonline.server.items.Item");
CtClass ctAction = classPool.get("com.wurmonline.server.behaviours.Action");
CtClass ctMethodsReligion = classPool.get("com.wurmonline.server.behaviours.MethodsReligion");
CtClass[] params1 = {
ctCreature,
ctCreature,
ctItem,
ctAction,
CtClass.floatType
};
String desc1 = Descriptor.ofMethod(CtClass.booleanType, params1);
replace = "if("+MethodsBestiary.class.getName()+".isSacrificeImmune($2)){" +
" performer.getCommunicator().sendNormalServerMessage(\"This creature cannot be sacrificed.\");" +
" return true;" +
"}";
Util.insertBeforeDescribed(thisClass, ctMethodsReligion, "sacrifice", desc1, replace);
Util.setReason("Disable afk training.");
CtClass ctCombatHandler = classPool.get("com.wurmonline.server.creatures.CombatHandler");
replace = "if("+MethodsBestiary.class.getName()+".blockSkillFrom($1, $0)){"+//"if($1.isPlayer() && $1.getTarget() != $0){" +
//" logger.info(\"Non-targeted mob detected - \" + $1.getName());" +
" $_ = true;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctCombatHandler, "setDamage", "isNoSkillFor", replace);
Util.instrumentDeclared(thisClass, ctCombatHandler, "checkDefenderParry", "isNoSkillFor", replace);
Util.instrumentDeclared(thisClass, ctCombatHandler, "checkShield", "isNoSkillFor", replace);
Util.instrumentDeclared(thisClass, ctCombatHandler, "setBonuses", "isNoSkillFor", replace);
CtMethod[] ctGetDamages = ctCombatHandler.getDeclaredMethods("getDamage");
for(CtMethod method : ctGetDamages){
method.instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isNoSkillFor")) {
m.replace("if("+MethodsBestiary.class.getName()+".blockSkillFrom($1, $0)){" + //"if($1.isPlayer() && $1.getTarget() != $0){" +
//" logger.info(\"Non-targeted mob detected - \" + $1.getName());" +
" $_ = true;" +
"}else{" +
" $_ = $proceed($$);" +
"}");
}
}
});
}
Util.setReason("Deny chargers walking through walls.");
CtClass ctPathFinder = classPool.get("com.wurmonline.server.creatures.ai.PathFinder");
replace = "if("+MethodsBestiary.class.getName()+".denyPathingOverride($0)){" +
" $_ = false;" +
"}else{" +
" $_ = $proceed($$);" +
"}";
Util.instrumentDeclared(thisClass, ctPathFinder, "canPass", "isGhost", replace);
Util.instrumentDeclared(thisClass, ctCreature, "setPathing", "isGhost", replace);
Util.instrumentDeclared(thisClass, ctCreature, "startPathingToTile", "isGhost", replace);
Util.instrumentDeclared(thisClass, ctCreature, "moveAlongPath", "isGhost", replace);
Util.instrumentDeclared(thisClass, ctCreature, "takeSimpleStep", "isGhost", replace);
Util.instrumentDeclared(thisClass, ctCreature, "die", "isGhost", replace);
Util.setReason("Apply random types to creatures in the wilderness.");
CtClass[] params2 = {
CtClass.intType,
CtClass.booleanType,
CtClass.floatType,
CtClass.floatType,
CtClass.floatType,
CtClass.intType,
classPool.get("java.lang.String"),
CtClass.byteType,
CtClass.byteType,
CtClass.byteType,
CtClass.booleanType,
CtClass.byteType,
CtClass.intType
};
String desc2 = Descriptor.ofMethod(ctCreature, params2);
replace = "$10 = "+MethodsBestiary.class.getName()+".newCreatureType($1, $10);";
Util.insertBeforeDescribed(thisClass, ctCreature, "doNew", desc2, replace);
Util.setReason("Enable archery against ghost targets.");
CtClass ctArchery = classPool.get("com.wurmonline.server.combat.Archery");
CtMethod[] archeryAttacks = ctArchery.getDeclaredMethods("attack");
for(CtMethod method : archeryAttacks){
method.instrument(new ExprEditor(){
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("isGhost")) {
m.replace("$_ = false;");
logger.info("Enabled archery against ghost targets in archery attack method.");
}
}
});
}
Util.setReason("Disable archery altogether against certain creatures.");
CtClass[] params3 = {
ctCreature,
ctCreature,
ctItem,
CtClass.floatType,
ctAction
};
String desc3 = Descriptor.ofMethod(CtClass.booleanType, params3);
replace = "if("+MethodsBestiary.class.getName()+".isArcheryImmune($1, $2)){"
+ " return true;"
+ "}";
Util.insertBeforeDescribed(thisClass, ctArchery, "attack", desc3, replace);
Util.setReason("Auto-Genesis a creature born on enchanted grass");
replace = MethodsBestiary.class.getName()+".checkEnchantedBreed(newCreature);"
+ "$_ = $proceed($$);";
Util.instrumentDeclared(thisClass, ctCreature, "checkPregnancy", "saveCreatureName", replace);
Util.setReason("Set custom corpse sizes.");
replace = "$_ = $proceed($$);"
+ "if("+MethodsBestiary.class.getName()+".hasCustomCorpseSize(this)){"
+ " "+MethodsBestiary.class.getName()+".setCorpseSizes(this, corpse);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "addItem", replace);
Util.setReason("Add spell resistance to custom creatures.");
replace = "float cResist = "+MethodsBestiary.class.getName()+".getCustomSpellResistance(this);" +
"if(cResist >= 0f){" +
" return cResist;" +
"}";
Util.insertBeforeDeclared(thisClass, ctCreature, "addSpellResistance", replace);
Util.setReason("Allow custom creatures to have breeding names.");
replace = "$_ = "+MethodsBestiary.class.getName()+".shouldBreedName(this);";
Util.instrumentDeclared(thisClass, ctCreature, "checkPregnancy", "isHorse", replace);
Util.setReason("Allow ghost creatures to breed (Chargers).");
CtClass ctMethodsCreatures = classPool.get("com.wurmonline.server.behaviours.MethodsCreatures");
replace = "$_ = false;";
Util.instrumentDeclared(thisClass, ctMethodsCreatures, "breed", "isGhost", replace);
Util.setReason("Allow ghost creatures to drop corpses.");
replace = "if("+MethodsBestiary.class.getName()+".isGhostCorpse(this)){"
+ " $_ = false;"
+ "}else{"
+ " $_ = $proceed($$);"
+ "}";
Util.instrumentDeclared(thisClass, ctCreature, "die", "isGhost", replace);
Util.setReason("Attach special effects to creatures.");
CtClass ctVirtualZone = classPool.get("com.wurmonline.server.zones.VirtualZone");
CtClass[] params4 = {
CtClass.longType,
CtClass.booleanType,
CtClass.longType,
CtClass.floatType,
CtClass.floatType,
CtClass.floatType
};
String desc4 = Descriptor.ofMethod(CtClass.booleanType, params4);
replace = "$_ = $proceed($$);" +
MethodsBestiary.class.getName()+".addCreatureSpecialEffect(copyId != -10 ? copyId : creatureId, $0, creature);";
Util.instrumentDescribed(thisClass, ctVirtualZone, "addCreature", desc4, "sendNewCreature", replace);
} catch ( CannotCompileException | NotFoundException | IllegalArgumentException | ClassCastException e) {
throw new HookException(e);
}
}
}

View File

@@ -15,12 +15,7 @@ import com.wurmonline.server.creatures.Creature;
import com.wurmonline.server.creatures.CreatureTemplate;
import com.wurmonline.server.creatures.CreatureTemplateFactory;
import com.wurmonline.server.creatures.Creatures;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemFactory;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.ItemTemplate;
import com.wurmonline.server.items.ItemTemplateFactory;
import com.wurmonline.server.items.NoSuchTemplateException;
import com.wurmonline.server.items.*;
import com.wurmonline.server.villages.Village;
import com.wurmonline.server.villages.Villages;
import mod.sin.armour.SpectralHide;
@@ -31,7 +26,8 @@ import mod.sin.items.EnchantersCrystal;
import mod.sin.items.FriyanTablet;
import mod.sin.wyvern.Bounty;
import mod.sin.wyvern.MiscChanges;
import mod.sin.wyvern.arena.Arena;
import mod.sin.wyvern.Arena;
import mod.sin.wyvern.Titans;
import mod.sin.wyvern.util.ItemUtil;
public class LootBounty {
@@ -66,7 +62,7 @@ public class LootBounty {
strBuilder += ", ";
}
}
MiscChanges.sendServerTabMessage(strBuilder, 0, 128, 255);
MiscChanges.sendServerTabMessage("event", strBuilder, 0, 128, 255);
logger.info("Broadcast loot assistance message success [Damage].");
}else{
logger.warning("Powerful creature "+mob.getName()+" died, but no players were credited to its death [Damage].");
@@ -123,6 +119,9 @@ public class LootBounty {
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
if(v != null){
break;
}
}
}
@@ -158,7 +157,7 @@ public class LootBounty {
try{
int mTemplate = mob.getTemplate().getTemplateId();
int lootTemplate = ItemList.drakeHide;
byte ctype = 0;
byte ctype;
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){
//if(mTemplate == 16 || mTemplate == 89 || mTemplate == 91 || mTemplate == 90 || mTemplate == 92){
@@ -213,9 +212,12 @@ public class LootBounty {
public static void handleChampionLoot(Item corpse){
try{
corpse.insertItem(ItemUtil.createRandomLootTool());
Item tool = ItemUtil.createRandomLootTool();
if (tool != null) {
corpse.insertItem(tool, true);
}
if(random.nextInt(100) < 75){
corpse.insertItem(ItemFactory.createItem((random.nextBoolean() ? 694 : 698), 30+(30*random.nextFloat()), ""));
corpse.insertItem(ItemFactory.createItem((random.nextBoolean() ? ItemList.adamantineBar : ItemList.glimmerSteelBar), 30+(30*random.nextFloat()), ""));
}
if(random.nextInt(100) < 5){
//int[] maskTemplates = {973, 974, 975, 976, 977, 978, 1099};
@@ -244,109 +246,40 @@ public class LootBounty {
}
public static void checkLootTable(Creature mob, Item corpse){
if(mob.isReborn() || mob.isBred()){
return;
}
double cretStr = Bounty.getCreatureStrength(mob);
int numCrystals = 0;
double crystalStr = cretStr;
/*double crystalStr = cretStr;
if(mob.isUnique()){ // Uniques will drop 3x as many, and have special properties to enable dropping rare and possibly supreme versions as well.
crystalStr *= 3;
}else if(Servers.localServer.PVPSERVER){ // Arena gives double the amount of crystals.
crystalStr *= 2.5;
}
// Award chaos crystals if the strength is high enough:
if(crystalStr > 3000){ // 30 copper
numCrystals += doRollingCrystalReward(mob, corpse, crystalStr, ChaosCrystal.templateId, 4, 5000);
/*double rollingCounter = cretStr;
int chance = 4;
int addedCrystals = 0;
if(mob.isUnique()){ // Uniques will drop 3x as many, and have special properties to enable dropping rare and possibly supreme versions as well.
rollingCounter *= 3;
}else if(Servers.localServer.PVPSERVER){
rollingCounter *= 2;
}
while(rollingCounter > 0){
// For every 50,000 creature strength, give a 1/8 chance at a chaos crystal
if(random.nextInt(chance+addedCrystals) == 0){
// The crystal quality is the cube root of the rolling counter, capped at 100 of course
Item chaosCrystal = ItemFactory.createItem(ChaosCrystal.templateId, (float) (random.nextFloat()*Math.min(100, Math.cbrt(rollingCounter))), "");
if(random.nextInt(40) == 0){
chaosCrystal.setRarity((byte) 1);
}else if(mob.isUnique() && random.nextInt(5) == 0){
if(random.nextInt(5) == 0){
chaosCrystal.setRarity((byte) 2);
}else{
chaosCrystal.setRarity((byte) 1);
}
}
corpse.insertItem(chaosCrystal);
addedCrystals++;
}
rollingCounter -= 5000;
}
if(addedCrystals > 0){
hasCrystals = true;
crystalStr *= 1.5;
}*/
// Award chaos crystals if the strength is high enough:
/*if(crystalStr > 3000){ // 30 copper
numCrystals += doRollingCrystalReward(mob, corpse, crystalStr, ChaosCrystal.templateId, 4, 5000);
}
if(crystalStr > 10000){ // 1 silver
numCrystals += doRollingCrystalReward(mob, corpse, crystalStr, EnchantersCrystal.templateId, 5, 20000);
/*double rollingCounter = cretStr;
int chance = 5;
int addedCrystals = 0;
if(mob.isUnique()){ // Uniques will drop 3x as many, and have special properties to enable dropping rare and possibly supreme versions as well.
rollingCounter *= 3;
}else if(Servers.localServer.PVPSERVER){
rollingCounter *= 2;
}
while(rollingCounter > 0){
// For every 200,000 creature strength, give a 1/8 chance at a enchanters crystal
if(random.nextInt(chance+addedCrystals) == 0){
// The crystal quality is the cube root of the rolling counter, capped at 100 of course
Item enchantersCrystal = ItemFactory.createItem(EnchantersCrystal.templateId, (float) (random.nextFloat()*Math.min(100, Math.cbrt(rollingCounter))), "");
if(random.nextInt(40) == 0){
enchantersCrystal.setRarity((byte) 1);
}else if(mob.isUnique() && random.nextInt(5) == 0){
if(random.nextInt(5) == 0){
enchantersCrystal.setRarity((byte) 2);
}else{
enchantersCrystal.setRarity((byte) 1);
}
}
corpse.insertItem(enchantersCrystal);
addedCrystals++;
}
rollingCounter -= 20000;
}
if(addedCrystals > 0){
hasCrystals = true;
}*/
}
boolean sendLootHelp = false;
// Begin loot table drops
if(mob.getTemplate().getTemplateId() == Reaper.templateId){
Server.getInstance().broadCastNormal("The "+mob.getName()+" has been slain.");
int templateId = mob.getTemplate().getTemplateId();
if(templateId == Reaper.templateId || templateId == SpectralDrake.templateId){
Server.getInstance().broadCastAlert("The "+mob.getName()+" has been slain. A new creature shall enter the realm shortly.");
sendLootHelp = true;
}else if(mob.getTemplate().getTemplateId() == SpectralDrake.templateId){
try{
logger.info("Generating spectral hide for the corpse of the "+mob.getName()+".");
for(int i = 0; i < 2; i++){
Item spectralHide = ItemFactory.createItem(SpectralHide.templateId, 50+(50*random.nextFloat()), "");
ItemTemplate itemTemplate = spectralHide.getTemplate();
int weightGrams = itemTemplate.getWeightGrams();
spectralHide.setWeight((int)((weightGrams*0.5f)+(weightGrams*0.5f*random.nextFloat())), true);
corpse.insertItem(spectralHide);
if(!mob.getStatus().isChampion()){
break;
}
}
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
Server.getInstance().broadCastNormal("The "+mob.getName()+" has been slain.");
sendLootHelp = true;
}else if(Arena.isTitan(mob)){
}else if(Titans.isTitan(mob)){
Server.getInstance().broadCastAlert("The Titan "+mob.getName()+" has been defeated!");
MiscChanges.sendGlobalFreedomChat(mob, "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180);
MiscChanges.sendServerTabMessage("The Titan "+mob.getName()+" has been defeated!", 255, 105, 180);
Arena.removeTitan(mob);
MiscChanges.sendServerTabMessage("titan", "The Titan "+mob.getName()+" has been defeated!", 255, 105, 180);
Item armour = ItemUtil.createRandomPlateChain(50f, 80f, Materials.MATERIAL_SERYLL, mob.getName());
if (armour != null) {
ItemUtil.applyEnchant(armour, (byte) 110, 80f+(Server.rand.nextInt(40))); // Harden
corpse.insertItem(armour, true);
}
Titans.removeTitan(mob);
sendLootHelp = true;
}
if(mob.getTemplate().getTemplateId() == CreatureTemplateFactory.GOBLIN_CID){
@@ -375,99 +308,12 @@ public class LootBounty {
if(mob.isUnique()){
// Spawn random addy/glimmer veins throughout the world
blessWorldWithMoonVeins(mob);
/*int i = 20;
while(i > 0){
int x = random.nextInt(Server.surfaceMesh.getSize());
int y = random.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
int type = Tiles.decodeType((int)Server.caveMesh.getTile(x, y));
if(height >= 100 && (type == Tiles.Tile.TILE_CAVE_WALL.id || type == Tiles.Tile.TILE_CAVE.id)){
Tiles.Tile tileType = random.nextBoolean() ? Tiles.Tile.TILE_CAVE_WALL_ORE_ADAMANTINE : Tiles.Tile.TILE_CAVE_WALL_ORE_GLIMMERSTEEL;
Server.caveMesh.setTile(x, y, Tiles.encode(Tiles.decodeHeight(Server.caveMesh.getTile(x, y)), tileType.id, Tiles.decodeData(Server.caveMesh.getTile(x, y))));
Players.getInstance().sendChangedTile(x, y, false, true);
Server.setCaveResource(x, y, 400+random.nextInt(600));
Village v = Villages.getVillage(x, y, true);
if (v == null) {
for (int vx = -50; vx < 50; vx += 5) {
for (int vy = -50; vy < 50 && (v = Villages.getVillage(x + vx, y + vy, true)) == null; vy += 5) {
}
}
}
if(v != null){
HistoryManager.addHistory(mob.getTemplate().getName(), "blesses the world with a "+tileType.getName()+" near "+v.getName()+"!");
}
logger.info("Placed a "+tileType.getName()+" at "+x+", "+y+" - "+height+" height");
i--;
}
}
Server.getInstance().broadCastAlert("The death of the "+mob.getTemplate().getName()+" has blessed the world with valuable ores!");*/
// Spawn 5-10 friyan tablets throughout the world.
spawnFriyanTablets();
/*i = 5+random.nextInt(5);
while(i > 0){
int x = random.nextInt(Server.surfaceMesh.getSize());
int y = random.nextInt(Server.surfaceMesh.getSize());
short height = Tiles.decodeHeight(Server.surfaceMesh.getTile(x, y));
if(height > 0 && height < 1000 && Creature.getTileSteepness(x, y, true)[1] < 30){
ItemFactory.createItem(FriyanTablet.templateId, 80f+random.nextInt(20), (float)x*4, (float)y*4, random.nextFloat()*360f, true, (byte)0, -10, "Friyanouce");
logger.info("Created a Tablet of Friyan at "+x+", "+y+".");
i--;
}
}*/
// 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);
/*int mTemplate = mob.getTemplate().getTemplateId();
int lootTemplate = ItemList.drakeHide;
byte ctype = 0;
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){
//if(mTemplate == 16 || mTemplate == 89 || mTemplate == 91 || mTemplate == 90 || mTemplate == 92){
ctype = 99; // Champion creature type
lootTemplate = ItemList.dragonScale;
//lootTemplate = 372;
}else{
ctype = (byte)Math.max(0, Server.rand.nextInt(17) - 5);
}
float x = mob.getPosX();
float y = mob.getPosY();
// Spawn the spectral drake.
//logger.info("Spawning a spectral drake.");
CreatureTemplate template = CreatureTemplateFactory.getInstance().getTemplate(SpectralDrake.templateId); // Spectral Drake ID: 2147483646
Creature spectralDrake = Creature.doNew(template.getTemplateId(), true, x, y, random.nextFloat()*360.0f, mob.getLayer(),
template.getName(), (byte)0, mob.getKingdomId(), ctype, false, (byte)150);
Server.getInstance().broadCastAction("The spirit of the "+mob.getTemplate().getName()+" is released into the world!", mob, 20);
Server.getInstance().broadCastAlert(spectralDrake.getName()+" is released from the soul of the "+mob.getTemplate().getName()+", seeking vengeance for its physical form!");
// Insert extra hide / scale
logger.info("Generating extra hide & scale to insert on the corpse of "+mob.getName()+".");
ItemTemplate itemTemplate = ItemTemplateFactory.getInstance().getTemplate(lootTemplate);
for(int 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 == 371 ? 3 : 1);
loot.setWeight((int)((weightGrams*0.1f)+(weightGrams*0.1f*random.nextFloat())), true);
corpse.insertItem(loot);
}
for(int i = 0; i < 4; 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 == 371 ? 3 : 1);
loot.setWeight((int)((weightGrams*0.05f)+(weightGrams*0.05f*random.nextFloat())), true);
spectralDrake.getInventory().insertItem(loot);
}*/
} else { // Spawn the reaper
try {
byte ctype = (byte)Math.max(0, Server.rand.nextInt(17) - 5);
@@ -479,91 +325,16 @@ public class LootBounty {
} catch (Exception e) {
e.printStackTrace();
}
}
}*/
sendLootHelp = true;
}
if(mob.getStatus().isChampion()){
// Champion mob loot
handleChampionLoot(corpse);
/*corpse.insertItem(ItemUtil.createRandomLootTool());
if(random.nextInt(100) < 75){
corpse.insertItem(ItemFactory.createItem((random.nextBoolean() ? 694 : 698), 30+(30*random.nextFloat()), ""));
}
if(random.nextInt(100) < 5){
int[] maskTemplates = {973, 974, 975, 976, 977, 978, 1099};
corpse.insertItem(ItemFactory.createItem(maskTemplates[random.nextInt(maskTemplates.length)], 90+(9*random.nextFloat()), ""));
}
if(random.nextInt(100) < 1){
Item bone = ItemFactory.createItem(867, 90+(10*random.nextFloat()), "");
bone.setRarity((byte)1);
if(random.nextInt(100) < 1){
bone.setRarity((byte)2);
}
corpse.insertItem(bone);
}*/
}
if(sendLootHelp){
logger.info("Beginning loot assistance message generation...");
displayLootAssistance(mob);
/*ArrayList<String> atkNames = new ArrayList<String>();
Map<Long, Long> attackers = Bounty.getAttackers(mob);
if(attackers != null){
for(Long wid : attackers.keySet()){
Creature cret = Creatures.getInstance().getCreatureOrNull(wid);
if(cret != null && cret.isPlayer()){
atkNames.add(Players.getInstance().getPlayer(wid).getName());
}
}
if(atkNames.size() > 0){
String atkStrBuilder = "Loot Assistance <Attackers> ("+mob.getName()+"): ";
while(atkNames.size() > 0){
int index = Server.rand.nextInt(atkNames.size());
atkStrBuilder += atkNames.get(index);
atkNames.remove(index);
if(atkNames.size() > 0){
atkStrBuilder += ", ";
}
}
MiscChanges.sendServerTabMessage(atkStrBuilder, 0, 128, 255);
logger.info("Broadcast loot assistance message success [Attackers].");
}else{
logger.warning("Powerful creature "+mob.getName()+" died, but no players were credited to its death [Attackers].");
}
}else{
logger.warning("Attackers was null for creature "+mob.getName()+" [Attackers].");
}*/
/*if(Bounty.dealtDamage.containsKey(mob.getWurmId())){
logger.info("Found the damageDealt entry, parsing...");
ArrayList<String> names = new ArrayList<String>();
ArrayList<Double> damages = new ArrayList<Double>();
for(long creatureId : Bounty.dealtDamage.get(mob.getWurmId()).keySet()){
if(Players.getInstance().getPlayerOrNull(creatureId) != null){
names.add(Players.getInstance().getPlayerOrNull(creatureId).getName());
damages.add(Bounty.dealtDamage.get(mob.getWurmId()).get(creatureId));
}else{
if(Creatures.getInstance().getCreatureOrNull(creatureId) != null){
logger.info("Skipping creature "+Creatures.getInstance().getCreatureOrNull(creatureId).getName()+" in loot assistance.");
}
}
}
logger.info("Names have been added: "+names);
String strBuilder = "Loot Assistance <Damagers> ("+mob.getName()+"): ";
DecimalFormat formatter = new DecimalFormat("#,###,###");
while(names.size() > 0){
int index = Server.rand.nextInt(names.size());
strBuilder += names.get(index);
strBuilder += " ["+formatter.format(Math.round(damages.get(index)))+"]";
names.remove(index);
damages.remove(index);
if(names.size() > 0){
strBuilder += ", ";
}
}
MiscChanges.sendServerTabMessage(strBuilder, 0, 128, 255);
logger.info("Broadcast loot assistance message success [Damage].");
}else{
logger.warning("Powerful creature "+mob.getName()+" died, but no players were credited to its death [Damage].");
}*/
}
if(numCrystals > 0){
Server.getInstance().broadCastAction(mob.getName()+" had something of interest...", mob, 5);

View File

@@ -1,6 +1,8 @@
package mod.sin.wyvern.bounty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.logging.Logger;
@@ -21,13 +23,17 @@ import mod.sin.armour.SpectralHide;
import mod.sin.creatures.Reaper;
import mod.sin.creatures.SpectralDrake;
import mod.sin.items.AffinityOrb;
import mod.sin.items.caches.TitanCache;
import mod.sin.wyvern.Bounty;
import mod.sin.wyvern.arena.Arena;
import mod.sin.wyvern.Arena;
import mod.sin.wyvern.Titans;
import mod.sin.wyvern.util.ItemUtil;
public class PlayerBounty {
public static final Logger logger = Logger.getLogger(PlayerBounty.class.getName());
protected static final Random random = new Random();
public static HashMap<String, Long> steamIdMap = new HashMap<>();
public static HashMap<Long, ArrayList<Long>> playersRewarded = new HashMap<>();
public static double getTypeBountyMod(Creature mob, String mobType){
if(!mob.isUnique()){
@@ -110,10 +116,21 @@ public class PlayerBounty {
public static void checkPlayerReward(Player player, Creature mob){
try{
if(mob.isReborn() || mob.isBred()){
return;
}
int mobTemplateId = mob.getTemplate().getTemplateId();
if(Bounty.dealtDamage.containsKey(mob.getWurmId()) && Bounty.dealtDamage.get(mob.getWurmId()).containsKey(player.getWurmId())){
long mobWurmId = mob.getWurmId();
if(playersRewarded.containsKey(mobWurmId)){
ArrayList<Long> steamArray = playersRewarded.get(mobWurmId);
if(steamArray.contains(steamIdMap.get(player.getName()))){
player.getCommunicator().sendSafeServerMessage("Another character has claimed the reward from this bounty.");
return;
}
}
if(Bounty.dealtDamage.containsKey(mobWurmId) && Bounty.dealtDamage.get(mobWurmId).containsKey(player.getWurmId())){
// -- Damage Dealt Rewards -- //
if(mob.isUnique()){
/*if(mob.isUnique()){
// Treasure boxes awarded to players who deal damage:
Item treasureBox = ItemUtil.createTreasureBox();
if(treasureBox != null){
@@ -121,18 +138,23 @@ public class PlayerBounty {
}else{
logger.warning("Error: Treasure box was not created properly!");
}
}
if(Arena.isTitan(mob)){
}*/
if(Titans.isTitan(mob)){
player.addTitle(Title.getTitle(700));
Item affinityOrb = ItemFactory.createItem(AffinityOrb.templateId, 99f, mob.getName());
player.getInventory().insertItem(affinityOrb, true);
Item titanCache = ItemFactory.createItem(TitanCache.templateId, 99f, mob.getName());
player.getInventory().insertItem(titanCache, true);
return;
}
double fightskill = player.getFightingSkill().getKnowledge();
if((mobTemplateId == Reaper.templateId || mobTemplateId == SpectralDrake.templateId) && fightskill >= 50){
//double fightskill = player.getFightingSkill().getKnowledge();
/*if((mobTemplateId == Reaper.templateId || mobTemplateId == SpectralDrake.templateId) && fightskill >= 50){
rewardPowerfulLoot(player, mob); // Reward affinity orb and enchant orb:
if(mob.getTemplate().getTemplateId() == SpectralDrake.templateId){
rewardSpectralLoot(player); // Reward spectral hide for spectral drakes
}
return; // If the player receives powerful loot, break the method completely and skip bounty.
}
}*/
// -- End Damage Dealt Rewards -- //
}
String mobName = mob.getTemplate().getName().toLowerCase();
@@ -143,63 +165,41 @@ public class PlayerBounty {
if(Bounty.reward.containsKey(mobName)){
iron = Bounty.reward.get(mobName); // Prioritize hardcoded values in the Bounty.reward list first
}else{
iron = java.lang.Math.round(cretStr); // Calculate bounty from creature strength if they do not exist in the reward list.
iron = Math.round(cretStr); // Calculate bounty from creature strength if they do not exist in the reward list.
}
if(Servers.localServer.PVPSERVER){
if(!mob.isUnique() && mob.getTemplate().getTemplateId() != SpectralDrake.templateId && mob.getTemplate().getTemplateId() != Reaper.templateId){
iron *= 2.5d;
iron *= 1.2d;
}
try {
/*try {
player.getSkills().getSkill(SkillList.MEDITATING).skillCheck(10, 0, false, 1); // Meditation skill gain
float faithMod = 1-(player.getFaith()/200f);
player.modifyFaith((((float)cretStr)*faithMod)/200000f); // Faith skill gain
} catch (NoSuchSkillException e) {
e.printStackTrace();
}
}*/
}
// Multiply bounty based on type
//if(mob.isAggHuman() || mob.getBaseCombatRating() > 10) {
iron *= getTypeBountyMod(mob, mobType);
/*if(!mob.isUnique()){
if (mobType.endsWith("fierce ")){
iron *= 1.5;
}else if (mobType.endsWith("angry ")){
iron *= 1.4;
}else if (mobType.endsWith("raging ")){
iron *= 1.6;
}else if (mobType.endsWith("slow ")){
iron *= 0.95;
}else if (mobType.endsWith("alert ")){
iron *= 1.2;
}else if (mobType.endsWith("greenish ")){
iron *= 1.7;
}else if (mobType.endsWith("lurking ")){
iron *= 1.1;
}else if (mobType.endsWith("sly ")){
iron *= 0.8;
}else if (mobType.endsWith("hardened ")){
iron *= 1.3;
}else if (mobType.endsWith("scared ")){
iron *= 0.85;
}else if (mobType.endsWith("diseased ")){
iron *= 0.9;
}else if (mobType.endsWith("champion ")){
iron *= 2.0;
}
}*/
player.addMoney(iron);
Item inventory = player.getInventory();
String coinMessage = Economy.getEconomy().getChangeFor(iron).getChangeString();
String strBuilder = "You are awarded " + coinMessage;
if((mob.isAggHuman() || mob.isMonster()) && !mob.isUnique() && !Servers.localServer.PVPSERVER){
Item creatureToken = ItemFactory.createItem(22765, 1+(99*random.nextFloat()), ""); // Creature Token ID: 22765
inventory.insertItem(creatureToken);
strBuilder += " and a "+creatureToken.getTemplate().getName();
}
strBuilder += " for slaying the "+mob.getName()+".";
strBuilder += " for slaying the " + mob.getName() + ".";
player.getCommunicator().sendSafeServerMessage(strBuilder);
}catch (NoSuchTemplateException | FailedException | IOException e) {
long playerSteamId = steamIdMap.get(player.getName());
if(playersRewarded.containsKey(mobWurmId)){
playersRewarded.get(mobWurmId).add(playerSteamId);
}else{
ArrayList<Long> steamArray = new ArrayList<>();
steamArray.add(playerSteamId);
playersRewarded.put(mobWurmId, steamArray);
}
//}
}catch (IOException | FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
} // checkPlayerReward
@@ -214,7 +214,6 @@ public class PlayerBounty {
logger.info(player.getName()+" killed "+creature.getName());
checkPlayerReward(player, creature);
} catch (IllegalArgumentException | ClassCastException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

View File

@@ -1,25 +1,19 @@
package mod.sin.wyvern.mastercraft;
import java.util.Objects;
import java.util.logging.Logger;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import com.wurmonline.server.Server;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.players.Titles;
import com.wurmonline.server.skills.Skill;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.*;
import javassist.bytecode.BadBytecode;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
import mod.sin.lib.Util;
import org.gotti.wurmunlimited.modloader.ReflectionUtil;
import org.gotti.wurmunlimited.modloader.classhooks.HookManager;
import java.util.Objects;
import java.util.logging.Logger;
public class Mastercraft {
private static Logger logger = Logger.getLogger(Mastercraft.class.getName());
@@ -86,6 +80,8 @@ public class Mastercraft {
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Drama_Queen", 551, "Drama Queen", "Drama Queen", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Zergling", 552, "Zergling", "Zergling", -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("Koza", 555, "Koza", "Koza", -1, "NORMAL");
// Contest Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Home_Decorator", 600, "Home Decorator", "Home Decorator", -1, "NORMAL");
@@ -94,8 +90,16 @@ public class Mastercraft {
// Special Event Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Titan_Slayer", 700, "Titanslayer", "Titanslayer", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Spectral_Slayer", 701, "Spectral Warrior", "Spectral Warrior", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Holdstrong_Architect", 701, "Holdstrong Architect", "Holdstrong Architect", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Stronghold_Architect", 701, "Stronghold Architect", "Stronghold Architect", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Holdstrong_Architect", 702, "Holdstrong Architect", "Holdstrong Architect", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Stronghold_Architect", 703, "Stronghold Architect", "Stronghold Architect", -1, "NORMAL");
// Donation titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Donator", 800, "Donator", "Donator", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Pazza_FavoriteGM", 801, "Sindusks Favourite GM", "Sindusks Favourite GM", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Warriorgen_ThatGuy", 802, "That Guy", "That Guy", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Eternallove_WarriorgensWife", 803, "Warriorgens Wife", "Warriorgens Wife", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Bambam_ThornOne", 804, "Thorn One", "Thorn One", -1, "NORMAL");
ExtendTitleEnum.getSingletonInstance().addExtendEntry("Svenja_CareDependant", 805, "The care-dependant", "The care-dependant", -1, "NORMAL");
// Characteristic Titles
ExtendTitleEnum.getSingletonInstance().addExtendEntry("MindLogic_Normal", 1000, "Logical", "Logical", 100, "NORMAL");
@@ -207,7 +211,9 @@ public class Mastercraft {
/*ctSkill.getDeclaredMethod("checkAdvance").insertBefore(""
+ "$1 = "+Mastercraft.class.getName()+".getNewDifficulty(this, $1, $2);");*/
Util.insertBeforeDeclared(thisClass, ctSkill, "checkAdvance", "$1 = "+Mastercraft.class.getName()+".getNewDifficulty(this, $1, $2);");
Util.setReason("Modify difficulty for skill checks in MasterCraft.");
String replace = "$1 = "+Mastercraft.class.getName()+".getNewDifficulty(this, $1, $2);";
Util.insertBeforeDeclared(thisClass, ctSkill, "checkAdvance", replace);
// - Increase spellcasting power for skilled channelers - //
CtClass ctSpell = classPool.get("com.wurmonline.server.spells.Spell");
@@ -219,7 +225,6 @@ public class Mastercraft {
m.replace("$2 += "+Mastercraft.class.getName()+".getCastPowerIncrease(castSkill);"
+ "$_ = $proceed($$);");
logger.info("Instrumented doEffect in run()");
return;
}
}
});
@@ -229,12 +234,10 @@ public class Mastercraft {
m.replace("$1 *= "+Mastercraft.class.getName()+".getFavorCostMultiplier(castSkill);"
+ "$_ = $proceed($$);");
logger.info("Instrumented depleteFavor in run()");
return;
}
}
});
}
} catch (CannotCompileException | NotFoundException e) {
e.printStackTrace();
}

View File

@@ -5,11 +5,7 @@ import java.util.logging.Logger;
import com.wurmonline.server.FailedException;
import com.wurmonline.server.Server;
import com.wurmonline.server.items.Item;
import com.wurmonline.server.items.ItemFactory;
import com.wurmonline.server.items.ItemList;
import com.wurmonline.server.items.ItemSpellEffects;
import com.wurmonline.server.items.NoSuchTemplateException;
import com.wurmonline.server.items.*;
import com.wurmonline.server.spells.SpellEffect;
import com.wurmonline.shared.constants.Enchants;
@@ -29,14 +25,110 @@ public class ItemUtil {
ItemList.cherryRed,
ItemList.cherryGreen,
ItemList.giantWalnut,
ItemList.tomeEruption,
ItemList.wandOfTheSeas,
//ItemList.tomeEruption,
//ItemList.wandOfTheSeas,
ItemList.libramNight,
ItemList.tomeMagicGreen,
ItemList.tomeMagicBlack,
ItemList.tomeMagicBlue,
ItemList.tomeMagicWhite
};
public static int[] plateChainTemplates = {
ItemList.plateBoot,
ItemList.plateGauntlet,
ItemList.plateHose,
ItemList.plateJacket,
ItemList.plateSleeve,
ItemList.chainBoot,
ItemList.chainCoif,
ItemList.chainGlove,
ItemList.chainHose,
ItemList.chainJacket,
ItemList.chainSleeve,
ItemList.helmetBasinet,
ItemList.helmetGreat,
ItemList.helmetOpen
};
public static int[] toolWeaponTemplates = {
ItemList.axeSmall,
ItemList.shieldMedium,
ItemList.hatchet,
ItemList.knifeCarving,
ItemList.pickAxe,
ItemList.swordLong,
ItemList.saw,
ItemList.shovel,
ItemList.rake,
ItemList.hammerMetal,
ItemList.hammerWood,
ItemList.anvilSmall,
ItemList.cheeseDrill,
ItemList.swordShort,
ItemList.swordTwoHander,
ItemList.shieldSmallWood,
ItemList.shieldSmallMetal,
ItemList.shieldMediumWood,
ItemList.shieldLargeWood,
ItemList.shieldLargeMetal,
ItemList.axeHuge,
ItemList.axeMedium,
ItemList.knifeButchering,
ItemList.fishingRodIronHook,
ItemList.stoneChisel,
ItemList.spindle,
ItemList.anvilLarge,
ItemList.grindstone,
ItemList.needleIron,
ItemList.knifeFood,
ItemList.sickle,
ItemList.scythe,
ItemList.maulLarge,
ItemList.maulSmall,
ItemList.maulMedium,
ItemList.file,
ItemList.awl,
ItemList.leatherKnife,
ItemList.scissors,
ItemList.clayShaper,
ItemList.spatula,
ItemList.fruitpress,
ItemList.bowShortNoString,
ItemList.bowMediumNoString,
ItemList.bowLongNoString,
ItemList.trowel,
ItemList.groomingBrush,
ItemList.spearLong,
ItemList.halberd,
ItemList.spearSteel,
ItemList.staffSteel
};
// 3,4,7,8,20,21,24,25,27,62,63,64,65,80,81,82,83,84,85,86,87,90,93,94,97,
// 103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,135,139,143,152,185,
// 202,215,257,258,259,267,268,274,275,276,277,278,279,280,281,282,283,284,285,286,287,290,291,292,296,
// 314,350,351,374,376,378,380,382,388,390,392,394,396,397,413,447,448,449,463,480,581,
// 621,623,623,623,623,640,641,642,643,647,702,703,704,705,706,707,710,711,747,749,774,922
public static void applyEnchant(Item item, byte enchant, float power){
ItemSpellEffects effs = item.getSpellEffects();
if(effs == null){
effs = new ItemSpellEffects(item.getWurmId());
}
SpellEffect eff = new SpellEffect(item.getWurmId(), enchant, power, 20000000);
effs.addSpellEffect(eff);
if(item.getDescription().length() > 0){
item.setDescription(item.getDescription()+" ");
}
item.setDescription(item.getDescription()+eff.getName().substring(0,1)+Math.round(power));
}
public static Item createRandomSorcery(byte charges){
try {
Item sorcery = ItemFactory.createItem(sorceryIds[Server.rand.nextInt(sorceryIds.length)], 90+(10*Server.rand.nextFloat()), null);
sorcery.setAuxData((byte) (3-charges));
return sorcery;
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
return null;
}
public static Item createEnchantOrb(float power){
byte[] enchantOrbEnchants = {
Enchants.BUFF_CIRCLE_CUNNING,
@@ -67,27 +159,74 @@ public class ItemUtil {
}
return null;
}
public static Item createRandomPlateChain(float minQL, float maxQL, byte material, String creator){
try {
Item armour = ItemFactory.createItem(plateChainTemplates[Server.rand.nextInt(plateChainTemplates.length)], minQL+((maxQL-minQL)*Server.rand.nextFloat()), creator);
armour.setMaterial(material);
return armour;
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
return null;
}
public static Item createRandomToolWeapon(float minQL, float maxQL, String creator){
try {
return ItemFactory.createItem(toolWeaponTemplates[Server.rand.nextInt(toolWeaponTemplates.length)], minQL+((maxQL-minQL)*Server.rand.nextFloat()), creator);
} catch (FailedException | NoSuchTemplateException e) {
e.printStackTrace();
}
return null;
}
public static Item createRandomLootTool(){
try{
int[] templates = {7, 8, 20, 24, 25, 27, 62, 93, 97};
int[] templates = {
ItemList.hatchet,
ItemList.knifeCarving,
ItemList.pickAxe,
ItemList.saw,
ItemList.shovel,
ItemList.rake,
ItemList.hammerMetal,
ItemList.knifeButchering,
ItemList.stoneChisel,
ItemList.anvilSmall
};
int template = templates[random.nextInt(templates.length)];
float quality = 100;
for(int i = 0; i < 3; i++){
quality = java.lang.Math.min(quality, java.lang.Math.max((float)10, 90*random.nextFloat()));
for(int i = 0; i < 2; i++){
quality = Math.min(quality, Math.max((float)10, 70*random.nextFloat()));
}
byte[] materials = {7, 8, 9, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 30, 30, 31, 31, 34, 34, 56, 57, 67};
byte[] materials = {
Materials.MATERIAL_GOLD,
Materials.MATERIAL_SILVER,
Materials.MATERIAL_STEEL, Materials.MATERIAL_STEEL, Materials.MATERIAL_STEEL,
Materials.MATERIAL_COPPER, Materials.MATERIAL_COPPER,
Materials.MATERIAL_IRON, Materials.MATERIAL_IRON, Materials.MATERIAL_IRON, Materials.MATERIAL_IRON,
Materials.MATERIAL_LEAD, Materials.MATERIAL_LEAD,
Materials.MATERIAL_ZINC, Materials.MATERIAL_ZINC,
Materials.MATERIAL_BRASS, Materials.MATERIAL_BRASS,
Materials.MATERIAL_BRONZE, Materials.MATERIAL_BRONZE,
Materials.MATERIAL_TIN, Materials.MATERIAL_TIN,
Materials.MATERIAL_ADAMANTINE,
Materials.MATERIAL_GLIMMERSTEEL,
Materials.MATERIAL_SERYLL
};
byte material = materials[random.nextInt(materials.length)];
byte rarity = 0;
if(random.nextInt(50) <= 2){
if(random.nextInt(80) <= 2){
rarity = 1;
}else if(random.nextInt(200) <= 2){
}else if(random.nextInt(250) <= 2){
rarity = 2;
}
byte[] enchants = {13, 13, 16, 16, 47};
byte[] enchants = {
Enchants.BUFF_WIND_OF_AGES, Enchants.BUFF_WIND_OF_AGES,
Enchants.BUFF_CIRCLE_CUNNING, Enchants.BUFF_CIRCLE_CUNNING,
Enchants.BUFF_BLESSINGDARK
};
byte enchant = enchants[random.nextInt(enchants.length)];
float power = 130;
float power = 100;
for(int i = 0; i < 2; i++){
power = java.lang.Math.min(power, 30+(100*random.nextFloat()));
power = Math.min(power, 20+(60*random.nextFloat()));
}
Item tool = ItemFactory.createItem(template, quality, material, rarity, "");
ItemSpellEffects effs = tool.getSpellEffects();
@@ -115,7 +254,6 @@ public class ItemUtil {
}
return treasureBox;
} catch (FailedException | NoSuchTemplateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;