Jump to content

Anticipating Zombies: edited zombie behavior - Now in Lua


Morry

Recommended Posts

Hello. This mod edits the lunge behavior of zombies, which is the part where most of them stretch out their arms and run towards you. Instead of heading directly towards the player, zombies now try to predict a player's future position to intercept them instead of constantly lagging behind them. Please try it out and tell me what you think of it.

 

qXqFJhk.png

 

Now redone in Lua! Currently singleplayer only, I can not access IsoZombie.target through Lua for some reason, so currently the first player is always used instead.

 

Steam Workshop version

 

update 1:

  • Fixed TargetVelocity. 
  • Lunging zombies only anticipate when then are near you, should prevent slow shamblers from attempting to out manouver you while being 10 meters away... 
  • While trying to run past zombies, the zombies should move more towards you instead of only cutting off your route

 

Known issues:

  • Singleplayer only.

 

anticipating zombies.zip

Edited by Morry
Mod updated
Link to comment
Share on other sites

Wow, talk about a new challenge. Meeting large hordes of Zombies would probably mean your certain doom, as maneuvering would get very hard. Please try and find a way for this mod to work without replacing files so it can be toggled on/off easily. Not that I complain, switching back and forth is a relatively easy task, but I know many people like me (that get anxious when messing with game files) would appreciate it.

 

3 hours ago, Morry said:

Known issues:

  • getMovementLastFrame() does not take collisions into account, so continuously running into an object might result in zombies predicting you beyond that object, even though you are effectively standing still.

For some reason, I imagined a guy in the middle of the street, running on a gym treadmill and zombies getting away from him. Now that would be clearing streets in style ;)

Link to comment
Share on other sites

I did not think it was possible at first but I rewrote the mod in Lua so java files do not have to be manually replaced anymore.

 

But now I have the problem that I can not access IsoZombie.target, probably because it is a variable instead of a function. I need to be able to access the zombie target in order to get the mod working with multiplayer. This could happen if getTarget() and setTarget() which get and set IsoZombie.target were added to IsoZombie. What would be the correct place to request such a thing?

Link to comment
Share on other sites

@Morry I notice that the behavior is limited to LungeState. Would you comment on the feasibility of the following changes?

 

- There are state machine targets like `WalkTowardState' et al. that could use running an intercept course.

- We'd need either a target or a tile location of the target.

- We'd need to invoke Bresenham over the target's position as well as the preferred intercept course. See that it's pointless to intercept with obstacles around. The non-antialiased Bresenham algorithm version.

 

Finally, the important bit:

- How feasible is it to hook the Java class loader and add `getTarget' method ourselves? This reminds me of Xposed on Android where one could "advice" the function, running around it, replacing it, running before or after, etc.

- Please keep in mind that messing with the class loader isn't something that could be downloaded from the Workshop. On the other hand, it can be used for all kinds of stuff, without the need to coordinate with the development team. If stuff is fixed in mainline after a time, good, but one could start modifying classes programmatically, and making all the stuff from the debugger visible to Lua.

 

What is the general sentiment about that kind of mod "helper"? Would users allow for it, despite the potential lack of sandboxing it causes? I can work on it if there are others that want to potentially use it.

 

See here for nitty gritty detail of what can be done:

https://github.com/krka/kahlua2/blob/64ff71a8b213f3a4d7b0319f974a878771a6ab89/j2se/src/se/krka/kahlua/j2se/KahluaTableImpl.java#L49

https://stackoverflow.com/questions/3560103/how-to-force-a-class-to-be-initialised

 

In fact one needn't a full "advice", merely add elements to existing kahlua2's metatable.

 

@Morry thank you for being responsive on the Steam comment page. Also I like your mod's general ideas.

Edited by sthalik
Link to comment
Share on other sites

@sthalik I did not really look that much other states for intercepting because I wanted to my first attempt simple. As long as you have an IsoMovingTarget target you'll be able to access the targets velocity, which you need for any intercepting. So I think it would be possible, but it might look silly if slow zombies try to intercept you from far away.

 

I have no idea how feasible it is to hook the class loader, being able to add methods would be great but with no workshop you might as well just make a java mod. And I am going to look into what you sent here

 

Link to comment
Share on other sites

@Morry It's only necessary to create a static intiializer that calls into kahlua, and forcing it to run. That's way less complex than a custom class loader which I suggested earlier.

 

See that there are apps requiring Xposed for Android on the official store. As an analogy to PZ, there can be Workshop mods that won't run without Java internals.

 

it might look silly if slow zombies try to intercept you from far away.

 

It's on the contrary actually in flight simulation. The distances are large enough (30-50 nautical miles) that PZ zombies seem fast :)

Link to comment
Share on other sites

  • 2 weeks later...

Hey,

 

I did a bit of researching and prototyping.

 

I'm able to inject code without creating a derivative work of PZ. That is, I don't need to provide a modified version of PZ's copyrighted bytecode.

 

BUT! I still need to modify it in the right place where Lua initializes its Java support, i.e. metatables et al. This is obviously a violation of the copyright agreement PZ comes with. Basically it's an executable change, except it's bytecode and not machine code. It's not a difference though. In case the PZ team considers this inappropriate, please say so and I'll stop all technically-infringing activity.

 

Things that don't work:

1) Static initializers in own code copied into .class won't work. The code has to be referenced by PZ code in order to load the static initializer, in Java.

2) Recompiling kahlua2. It has some mild modifications that won't allow for a drop-in replacement of the entire kahlua codebase.[1]

3) Adding do kahlua metatables for Java classes. I tried adding to _call or _index and there was no effect. What's strange is that the metatables are empty after exposing the Java classes.

 

My prototype approach is to expose global Lua functions instead. That thing always works. I'd go for[2]:

 

__get_field_descriptor(name, some-exposed-java-datum) -- get Java's "Field" class via reflection

__get_field_value(datum, descriptor) -- get given datum's actual field value.

 

I haven't done any of the prototype approach. No time.

 

Things that might work:

 

1) Find out what the kahlua2 modifications are and replicate them from scratch to make a drop-in replacement. Too much effort, I won't do it. Still able to defeat via particular copyright legal clauses.

2) Modify just _some_ of kahlua2 code. It's brittle and still theoretically able to defeat via copyright.

 

Things depend on whether the PZ authors are hostile or neutral toward the approach. In the former case it's pointless to work on it since it won't be visible in modding community anyway.

 

[1] It crashed on startup missing "currentFile" in some of kahlua2 classes.

[2] After the prototype stage, we'd need to whitelist exposed fields since unlimited access to internal values is a can of worms.

 

sh

Link to comment
Share on other sites

  • 3 weeks later...

@sthalik Maybe nobody just knows about this function or the devs have forgotten that it exists, I've at least never seen anyone talk about it on the forum. But I found a much easier solution for accessing fields. This method in LuaManager gets the value of a specified field. There are also methods to access the number of fields and getting a field from an object. I will update the mod to use this soon...

 

   @LuaMethod(name="getClassFieldVal", global=true)
    public static Object getClassFieldVal(Object o, Field field)
    {
      try
      {
        return field.get(o);
      }
      catch (Exception ex) {}
      return "<private>";
    }

 

Link to comment
Share on other sites

  • 2 weeks later...

Well I updated it with getClassFieldVal, so the zombie target is known. But it still does not work in multiplayer. Do zombies in multiplayer use different code than in single-player or something like that?

Link to comment
Share on other sites

@jinoz First because I could not access the target of zombies. But I have found a way to do that, but it still does not work for some reason. I don't know why but it just does the normal lunge behavior while in multiplayer.

Edited by Morry
Link to comment
Share on other sites

  • 1 year later...

This is really interesting but I find it strange because zombies aren't technically supposed to be intelligent enough to predict there preys movements and plan tactics like that. It kind of goes against the standard zombie behavior of following their prey as a base instinct. I'm just saying. this is cool though, so not insulting or anything. I'm just saying really.

Link to comment
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
×
×
  • Create New...