joedobo

[WIP] Ghost Tower Guard Mod

Recommended Posts

This server mod (for use with Ago's server modlauncher) will add custom guard towers designed for PvE and especially folks who would like the option to not fight . The primary goal with these is to have simple towers not subjected to vanilla WU tower mechanics. My goal is to have few restriction over them. The server owner will be able to configure guard strength. This customed strength could be anything between not being able to kill a rat all the way to one hit killing a venerable red dragon. After asking for help within the tower's range a guard will be created right on top of the mob and immediately start attacking it. It's a ghost so they can just appear wherever, right?

 

Source on GitHub: https://github.com/Joedobo27/GhostTowerGuardMod

No releases at the moment as it's not ready. Although, the code is on github if you wanted to clone it and mess around.

 

Requires 

 

 

I could use some help at this point (1/28/2019). 

#1) The onPlayerMessage() modloader hook so I can trigger events when players ask for help is loading WU bases classes too early and causing an error:
java.lang.RuntimeException: com.wurmonline.server.players.Player class is frozen

 

There is a bunch of these too:

[07:25:23 AM] WARNING org.gotti.wurmunlimited.modloader.EarlyLoadingChecker: Mod GhostTowerGuardMod loaded server class com.wurmonline.server.creatures.Creature during phase load

 

When I remove the PlayerMessageListener interface and its required methods the error goes away.

 

 

#2) Also, I"m not sure if creature AI can be setup to destroy itself if its target no longer exists. I want to create a ghost, have it target and attack the mob. Once the target is dead have the ghost disappear and delete itself. I'm not asking you to do this. I just want to know how difficult it is before I start digging into it. I've never done anything with creature AI.

Share this post


Link to post
Share on other sites
1 hour ago, joedobo said:

#1) The onPlayerMessage() modloader hook so I can trigger events when players ask for help is loading WU bases classes too early and causing an error:

 

java.lang.RuntimeException: com.wurmonline.server.players.Player class is frozen

 

There is a bunch of these too:

[07:25:23 AM] WARNING org.gotti.wurmunlimited.modloader.EarlyLoadingChecker: Mod GhostTowerGuardMod loaded server class com.wurmonline.server.creatures.Creature during phase load

 

When I remove the PlayerMessageListener interface and its required methods the error goes away.

I haven't quite gotten my head around load order myself yet, so someone may have a better answer.  But I just gave it a quick try and if you move the onPlayerMessage code out of your mod class and into another and just call that from the onPlayerMessage method it doesn't cause the same error.

 

There is probably a better way, but it should get things done as a workaround.  Not tested it fully of course.

1 hour ago, joedobo said:

#2) Also, I"m not sure if creature AI can be setup to destroy itself if its target no longer exists. I want to create a ghost, have it target and attack the mob. Once the target is dead have the ghost disappear and delete itself. I'm not asking you to do this. I just want to know how difficult it is before I start digging into it. I've never done anything with creature AI.

Only just learning about it myself, but I've thought of two ideas.  One, create your own extension to the CreatureAI class, then in the pollCreature method returning true signals that the Creature should die.  The big drawback to this one is that you'd need to implement the combat stuff yourself.  The easier way would be to hook on setOpponent and check if it receives null, then just call the die method.

Share this post


Link to post
Share on other sites
4 hours ago, joedobo said:

#2) Also, I"m not sure if creature AI can be setup to destroy itself if its target no longer exists. I want to create a ghost, have it target and attack the mob. Once the target is dead have the ghost disappear and delete itself. I'm not asking you to do this. I just want to know how difficult it is before I start digging into it. I've never done anything with creature AI.

 

Something like this, just instead of owner check for target

 

https://github.com/bdew-wurm/minipets/blob/master/src/main/java/net/bdew/wurm/minipets/MiniPetAI.java#L19-L23

Share this post


Link to post
Share on other sites

@joedobo After so many times of running around in circles with a troll chasing me, waiting for the guards to catch up, I think I'm going to love this mod!

Share this post


Link to post
Share on other sites

I'm make slow but steady progress with this. I fixed all the early loader problems by relocating code and using long wurmId's instead of wurm objects.

 

Here are some new questions:

1. I'd like to run object clean up code to handle edge cases. Every 6 hours or so I want to check that the GhostTower objects have a matching Wurm item object and if that is lacking remove the tower. I can inject the needed code into say Item.poll() but I don't understand the polling frequency. And I need this to make a proper RNG roll that success about every 6 hours.

 

2. I foresee some doofus using these to grief people. I'm pretty sure they will attack other players at the moment. Also, it would be easy to build a tower next to a deed and kill all the animals on it. Currently I'm think about these limitations:

  •  Ghosts won't attack targets of the same kingdom as the player asking for help.
  • No attacking hitched creatures.
  • does branding make an animal of the same kingdom? 
  • things like branding, cared-for, tame, equipped-with-gear are all possible filters for blocking.
  • Any other ideas?

3. Where do others put creature template creation? I put mine in onServerStarted() but that seem too late.

Share this post


Link to post
Share on other sites
On 2/23/2019 at 7:01 PM, joedobo said:

1. I'd like to run object clean up code to handle edge cases. Every 6 hours or so I want to check that the GhostTower objects have a matching Wurm item object and if that is lacking remove the tower. I can inject the needed code into say Item.poll() but I don't understand the polling frequency. And I need this to make a proper RNG roll that success about every 6 hours.

I've not used it myself yet, but modlauncher has a ServerPollListener interface.  Not sure how often it gets called though.

On 2/23/2019 at 7:01 PM, joedobo said:

3. Where do others put creature template creation? I put mine in onServerStarted() but that seem too late.

I just follow ago's creature demo and put it in init and it seems to work fine.  I imagine there might be errors with creatures being loaded from the database during server load and not finding the template?  This might not have happened with yours as they are created on demand rather than "living" on the server.

On 2/23/2019 at 7:01 PM, joedobo said:
  • Any other ideas?

The one thought I had is you could also check if they are on a village tile, unless the asker has some appropriate village permissions.

Share this post


Link to post
Share on other sites

I'm surprised putting things in init doesn't cause a bunch of class frozen problems with javassist edits. Now, if you were careful and didn't use any WU classes it could work out. It's clearly setup that way in ago's creature demo and that has worked for some time.

Share this post


Link to post
Share on other sites

init should work if you use ModCreatures and are careful about what you reference in the constructor.

 

personally i do mine from onItemTemplatesCreated (and use CreatureTemplateBuilder directly) - it's early enough and safe in terms of freezing

Share this post


Link to post
Share on other sites

Hopefully I've got enough checks in here to stop tower griefing. 

 

 

Here's the two I hope will work best to protect player's deeded zoos. Thanks for the tip@Mthec

// NO attacking creatures that aren't threats.
 if (Arrays.stream(player.getLatestAttackers())
		.noneMatch(longId -> longId == target.getWurmId())) {
	 communicator.getPlayer().getCommunicator().sendNormalServerMessage(
			 "Ghosts won't attack a creature that isn't currently or hasn't recently threatened you.");
	 return MessagePolicy.PASS;
 }
 // No village permission to attack on deed.
@Nullable Village occupiedVillage = Villages.getVillage(target.getTileX(), target.getTileY(), target.isOnSurface());
if (occupiedVillage != null && (!occupiedVillage.isActionAllowed((short)326, player) ||
		!occupiedVillage.isActionAllowed((short)716, player))) {
	communicator.getPlayer().getCommunicator().sendNormalServerMessage(
			String.format("Ghosts refuse to help you because village %s has denied you attacking permission",
					occupiedVillage.getName()));
}

The others are here if your curious:     https://github.com/Joedobo27/GhostTowerGuardMod/blob/cd6a58f42d960e0d6527aac05d4328013d2ac97f/src/main/java/com/joedobo27/gtgm/GhostTower.java#L38

 

Lastly,
I'm have a sporadic issue with initializing Wurm classes (Creature, Player) in the javassist intended init() section. It's really weird so I'd like to somehow catch this when it happens and just just skip the mod. I'd rather have a warning in the log file and have modlauncher skip the mod then have it all crash. I'm not sure how difficult it is to do this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now