Jump to content

How Script Commands Get Translated To Java Commands


lulu58e2

Recommended Posts

(I apologize if this is covered elsewhere; I searched but didn't see anything. I might not be searching correctly)

 

I read http://www.projectzomboid.com/modtools/ModdingGuide2.rtf but I'm still trying to sort out how the scripting works and was confused by calls like:

 

Gaurd1.SayIdle("I need some help ...")

 

The zombie.scripting.objects.Script class will actually take that line, chop it up and:

- Find the zombie.scripting.commands Class whose name matches "SayIdle"

- Create an instance of that command object

- Look for an aliased object called "Gaurd1" (whatever object SayIdle(...) is being "called" on)

- Bundle all the parameters into an array (in this case just one)

- call init(object, [param1, ...]) on the command

- return the command

 

So really what you're calling is: 

new SayIdle().init(aliasedInstanceOfOther, ["I need some help"])

... except you get an instance of the command back as well.

 

Note that the World, Tutorial and Quest commands all take objects called "World", "Tutorial" and "Quest".

e.g.

World.PlaySoundEffect("firealarm", ...)

 

See zombie.scripting.commands.CommandFactory for the list of commands you can call.

These are the current commands (build 25)

(Notice there is a LuaCall command!)

ActualizeCommand
AddEnemy
AddEquipItemTask
AddFindItemTask
AddGotoLocationTask
AddHardCodedTask
AddHelpIconToUIElement
AddHelpIconToWorld
AddInventory
AddScriptConditionTask
AddToGroup
AddUseItemOnTask
AimWhileStationary
AllowBehaviours
AllowConversation
Anger
Attack
Call
CallAndWait
CharactersAlreadyInScript
CreateQuest
CreateZombieSwarm
Decrement
Die
DisableTutorialZombieControl
Enabled
EquipItem
Exists
FaceCommand
HasInventory
HasTrait
Increment
IncrementCharacterScriptFlag
InRange
IsActivated
IsAggressive
IsAggressivePose
IsCharacterScriptFlagEqualTo
IsCharacterScriptFlagOver
IsDead
IsFlagValue
IsFriendly
IsGreaterThan
IsGreaterThanEqualTo
IsInGroup
IsInGroupWith
IsInRoom
IsInside
IsLastFiredParameter
IsLeaderOfGroup
IsLessThan
IsLessThanEqualTo
IsNeutral
IsNight
IsNumberOfEnemiesOver
IsNumberOfEnemiesUnder
IsNumberOfLocalOver
IsNumberOfLocalUnder
IsNumberOfNeutralOver
IsNumberOfNeutralUnder
IsOn
IsOnFloor
IsPlayer
IsPlaying
IsSpeaking
LoadTexturePage
LockHud
LockQuest
LuaCall
MetCountIsOver
NamedOrder
Order
Pause
PauseAllScriptsExcept
PlaySoundEffect
PlayWorldSoundEffect
PopOrder
ProcessAlways
ProcessNever
RegisterOneTime
RemoveNamedOrder
Resume
ResumeAllScriptsExcept
RunScriptOnComplete
SayAt
SayCommand
SayIdle
SetFlag
SetModuleAlias
SetZombieLimit
Sleep
SpawnZombie
StartFire
StopAction
StopAllScriptsContaining
StopAllScriptsExcept
StopAllScriptsExceptContaining
StopScript
TestStat
TimeSinceLastRan
ToggleActivatable
TryToTeamUp
UnlockLast
UnlockLastButHide
UnlockQuest
UnlockTaskOnComplete
UnlockTasksOnComplete
WaitCommand
WalkCommand
WalkToLastHeardSound
WalkToLastKnownLocationOf
WalkWithinRangeOf
Link to comment
Share on other sites

I have been using the java doc, http://theindiestone.com/zomboidjavadocs/ , which has an overwhelming amount of commands you can call in java from within a project zomboid mod.  The lack of descriptions of what they do is shocking however.  I haven't been able to do very much modding because I just have no idea what methods to call.

 

This command factory you linked is superb, and the first thing on the agenda for my server is going to be getting a questing system up and running.  I didn't even know there were Quest methods/functions in the mod originally!

 

Anyway, cheers for pointing out this command factory list. 

Link to comment
Share on other sites

Here are my quick notes on what different commands do; I didn't read into the code too much and I'm just getting into the code so some of these are probably a little off. If anyone finds it useful and I can add more details.

 

zombie.scripting.commands.Character <- Being re-written, won't work for long

(Player / Zombie / NPC commands)

ActualizeCommand
 
         - (owner, [waypoint, x, y, z])
         - Actualizes (instantiates) the character belonging to the owner (?)
 
AddEnemey
 
    - Removes the character from a group if the leader is now an enemy,
      otherwise removes the other member from the group
 
    - Adds the other character as an enemy
 
AimWhileStationary
    
    - Aims at nothing or another character
 
HasInventory /
AddInventory
 
    - Checks if the player's ScriptContainer (for this module?) has an actual ItemContainer
      with an item with the name specified
 
        - or adds the item (AddInventory)
 
FaceCommand
 
    - Face another character or a direction
 
Die
 
    - Creates a dead body based on an IsoGameCharacter, kills the character
 
AddToGroup /
IsInGroup /
IsInGroupWith /
IsLeaderOfGroup /
IsNumberOfEnemiesOver /
IsNumberOfLocalOver / Under (nearby characters? uses IsoGameCharacter.getLocalList() )
IsNumberOfNeutralOver / Under
IsMetCountOver
TryToTeamUp (just sets flag that user is trying to team up)
 
    - Adds a character to a group or checks if in group or in group with
 
AllowBehaviours / 
AllowConversation
 
    - Set whether this character is allowed X
 
HasTrait /
IsAggressive /
IsAggressivePose /
IsDead (health and body damage health both above zero)
IsInRoom (any room)
IsInside (inside a room)
IsNeutral /
IsSpeaking / 
TestStat (Compassion, Bravery, Loner, Temper) (like a dice roll in D&D) /
IsPlayer (Instance of IsoPlayer) /
IsOnFloor (X, or between floors X and Y)
 
    - Checks if an IsoCharacter has a trait, or is X, or has X animation (Pose)
 
Exists
 
    - Checks if the currentinstance has the IsoGameCharacter OR
      if this module has the ScriptCharacter OR
      if this module's luaMap has this owner as a key
 
EquipItem
 
    If the IsoGameCharacter has the item, put in primary hand
 
Attack
 
    If the IsoGameCharacter exists, or the module has the character with an
    actualized IsoGameCharacter, then tell the IsoGameCharacter (casted to
    an IsoLivingCharacter) to attempt an attack
 
Anger
    
    set IsoCharacterAnger
 
IncrementCharacterFlag /
IsCharacterScriptFlagEqualTo /
IsCharacterScriptFlagOver
 
    Creates a "flag" with value one for an IsoCharacter and gives it a name
    or increments the "flag" (counter)
 
InRange
 
    Checks if character is in range of another character or a waypoint using
    IsoUtils.DistanceManhattan
 
WalkWIthinRangeOf /
WalkToLastKnownLocationOf /
WalkToLastHeardSound /
WalkCommand
 
    Calls out to PathFindBehaviour and keeps checking if the 
    player is in range yet in the update() function
 
StringFunctions - not a command, just a utility in the namespace
 
StopAction
 
    Stop all actions in queue
 
Sleep 
 
    Obvious
 
SayIdle /
SayCommand /
SayAt
 
    Says something, not sure what
 
Order / 
NamedOrder (extends Order) /
RemoveNamedOrder
 
    Seems characters can have a list of orders: Idle, Follow, Face, FollowStrict
 
    See FaceOrder, FollowOrder
 
    FollowStrict seems to put .. I dunno
 
IsOn
 
    No idea. Doesn't seem to do anything.

 

zombie.scripting.commands.quest <-- Being re-written, won't work for long

AddEquipItemTask /
AddFindItemTask /
etc., etc.
 
    Uses QuestCreate.AddQuestTask_Foo(name, desc, item, num)

 

zombie.scripting.commands.Script

Call 
 
    Run a script
 
    Something to do with module.RandomSelectorMap.containsKey(this.position) ?
 
CallAndWait
 
    IsFinished returns false until ScriptManager says this script isn't "playing" anymore
 
CharactersAlreadyInScript
 
    You can negate this, so it's a boolean
 
    No idea what it means to have a character in a script. Maybe instanced?
 
IsPlaying /
Pause / 
Resume /
Stop
 
    Uses ScriptManager like CallAndWait

 

zombie.scripting.commands (and a few sub-namespaces that are small)

 

- BaseCommand
 
    Command on which all other commands are based (i.e. extended from)
 
    begin(), IsFinished(), update(), init(String paramString, String[] paramArrayOfString)
    DoesInstantly(), getValue(), Finish(), AllowCharacterBehaviour(String scriptCharacter)
    updateSkip()
 
    this.module is a ScriptModule
 
- CommandFactory
 
    (Not a command you call directly: used to create Java instances of Commands based on their string name,
     e.g. "LoadTexturePage")
 
    Creates a TON of different commands based on String names
 
- ConditionalCommand
 
    Allows you to add a script that runs on a conditional as well as another optional
    else script that runs on an else conditional
 
- LoadTexturePage
 
    Uses LoadTexturePage.WatchPair with TexturePackage.getPackage
 
- PauseAllScriptsExcept /
  ResumeAllScriptsExcept /
  StopAllScriptsContaining /
  StopAllScriptsExcept /
  StopAllScriptsExceptContaining
 
    Uses ScriptManager to find all [other] scripts and pause / resume / stop them
 
- SetModuleAlias
 
    Uses ScriptManager to set aliases on a module
 
- WaitCommand
 
    Wait for N * 30 frams (N seconds @ 30fps ?) or until specified condition passes
 
- IsActivated /
  ToggleActivatable
 
    Checks to see if a module is both Activatable and Activated (or toggles it)
 
.DayNight.isNight
 
    Time is between 8pm and 6am
 
.Flags.*
 
    Inc, Dec, Set, Check module flags, different than character flags
 
.Hook.RegisterOneTime
 
    Use the script manager to run a script once when an event occurs
 
.Lua.LuaCall
 
    Uses the LuaManager to call a LuaClosure with Kahlua tables 
 
    I've heard of tables from the forums, but no idea what they are
 
.Module.Enabled
 
    Set a module to enabled or disabled (anything but "true" means disabled)
 
    Sometimes they use foo or !foo, in this case they use "true" or anything else
 
.Trigger.IsLastFiredParameter
 
    Looks up a trigger list by name and checks to see if the param specified by 
    position (0, 1, 2) has the specified value in the first parameter in the list
    (which sounds like it's the last fired trigger)
 
.Trigger.ProcessAlways /
.Trigger.ProcessNever
 
    (Un)lock all triggers in the "CustomTriggerMap" by "position"
 
.Trigger.TimeSinceLastRan (has more than N * 30 frames expired since last run)
 
    Use ScriptManager and call .instance.CustomTriggerLastRan with the trigger name
    and see if it ran more than N * 30 frams ago
 
.World.CreateZombieSwarm /
          .SpawnZombie (with KeepItReal set to true always)
 
    Specify how many and a rectangle
 
.World.PlaySoundEffect
 
    ("World", [format, sound, position, pitchVar, radius, volume, ignoreOutside])
 
    Format = "WAV" or "OGG"
 
    Uses SoundManager
 
.World.PlayWorldSoundEffect
 
    Similar to PlaySoundEffect but uses WorldSoundManager and just has
 
    ("World", [position, radius, volume])
 
    Maybe for gun shots, helicopters, etc.?
 
.World.StartFire
 
    ("World", [position, energy])
 
    position is a string that is used by this.module.getWaypoint(...)
Link to comment
Share on other sites

Right now I'm mostly just trying to get my bearings in the Java, Lua and .txt scripting code. 

 

I'm working on a chainsaw mod and I have all kinds of stuff I want to do: 

- use gas while idling (done)

- idle sound (done, uses Lua Events.OnTick)

  - I was thinking of using a custom trigger or Lua Events.onSomething

- use more gas while swinging

- swing sound (done!)

- Animation

- Sprites

etc. 

Link to comment
Share on other sites

Oh, erm, this is old stuff, NPC/Quest/Tutorial is being re-write at the moment, so everything there won't work...

 

What you need to do exactly ?

 

Is the .txt file scripting going to stay around or is that all getting transitioned into Lua? 

Link to comment
Share on other sites

If you're interested in the NPC scripting specifically, there was a mondoid on the topic a while ago (I've linked it down below). The devs at least seem to be using some sort of scripting tool to make the stuff happen in stead of or more likely in addition to basic coding. We might have something similar at some point, made done by the devs themselves...

 

Todays Mondoid mentioned the tools again:

 

 

Finally Chris is back in the world of NPCs, where he shall probably remain for some time until we’re ready to start showing stuff, and is preparing a whole bunch of stuff to hand over to RingoD and Will, along with EasyPickin’s awesome NPC flowchart scripting tool.

 

Here's some other quotes I found on the subject:

Mondoid, 17th of February, 2014

 


A. From a scripting angle, not recently. We’ve been working on an NPC scripting editor that will make it easier to develop and mod the NPC behaviours, and the tutorial needs transplanting into the new system. Once that’s in we should be able to fly through the tutorial to get it to where it was. As NPC development dials back up this is pretty much top of the list. (Lemmy)

 

Mondoid Jul 15, 2013

 


The results have been exciting, and we now have a system that allows us to quickly define complex branching NPC scenes within the meta-game, with nodes such as ‘WalkTo’ and ‘Say’ and ways to determine how angry an NPC is or how tired they are. The beauty of this system is it doesn’t require programming knowledge to implement scenes, as well as looking pretty to boot. To other indie devs out there, it comes highly recommended and we may write more on how it can be leveraged directly in your game at a later date.
 
Modders need not worry, as we fully intend to extend our own toolset to allow our own propriatry free system in the future, but speed and ease of finishing the meta-game and NPCs is of prime importance at the moment.
 
During our SHAZAM! we’ve discussed new dialogue that Will will (will) be writing up soon, adding a whole wealth of insults, chats and plotting to round up all elements of the meta-game functionality that doesn’t have dialogue currently. Looking at the mountain of Will’s dialogue that RingoD has scripted up, it’s very exciting how quickly we should be able to get it in.

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...