[Plugin] Shoebill 1.1 - SA-MP Java Development Kit

I'm wondering about PlayerKeyStateChangeEvent... Why is there only getOldState() method? What about getNewState()?
Reply

@valych: Use the player.getKeyState() in the event to get the new key state.
Reply

@mk124: dammit, forgot to check player's methods, thanks
Reply

Animations. They don't seem to be working, atleast this one:

Код:
player.applyAnimation("CRACK", "crackdeth2", 4f, 1, 0, 0, 0, 0, 0);
I tried preloading animation, like in Pawn but that resulted in a client crash.
Reply

@Su37Erich: You only need to create variables for timers (it's not a normal behavior, it's a shoebill thing) to prevent forgotten timers that make memory leaks.
Reply

Hello again
I made this post since I am really frustrated. I have been trying to do a design for create Jobs but simply I can't.
I have tried the following:
- Singleton class (Reason: I need only an instance for the main class: Jobs and I need to pass the EventManager object. After it I should be able to create and destroy Job objects, like TruckDriver)
- Static abstract class with subclasses (I need the same of above, trying to do it in another way)
- Static class (How to get the EventManager? with a method? when?)
- Normal class (Class I am trying to do)

And the only thing I have done is the following:

PHP код:
import net.gtaun.shoebill.common.command.Command;
import net.gtaun.shoebill.common.command.CommandHelp;
import net.gtaun.shoebill.common.command.PlayerCommandManager;
import net.gtaun.util.event.EventManager;
import net.gtaun.util.event.HandlerPriority;
/**
 * Created by Erich on 05/03/2016.
 */
public class Jobs{
    private 
EventManager events;
    private 
PlayerCommandManager commandEvents;
    public 
Jobs(EventManager events){
        
this.eventsevents;
        
commandEvents= new PlayerCommandManager(events);
        
commandEvents.installCommandHandler(HandlerPriority.NORMAL);
        
commandEvents.registerCommands(new JobCommands());
    }
//I am now thinking about to add something like: enablePilotJob()
    
public class Pilot{
        
Pilot(){
                
//Do some stuff here
        
}
    }
    public class 
JobCommands{
        @
Command
        
public boolean job(){
            return 
true;
        }
        public 
boolean leave(String option){
            if(!
option.contains("job")){
                return 
true;
            }
            return 
true;
        }
    }

Here is the design I have planned
Jobs (Superclass)
KindOfJob(Thinking about it)
Pilot is a job so it'll need the "Job" variables and methods
Truck driver is a job so it'll need the "Job" variables and methods
Jobs class will be dependent of some classes, like ePlayer class to see if the player is using a checkpoint
And now my mind just exploded about the desing

I really appreciate any help about this or a link where I can learn about OOP desing, that to be honest, seems to be much more difficult than debugging a 100k lines non-OO program.
Reply

@Su37Erich: Why not create an abstract, parent class that defines all the things that jobs have in comon(for example name or location). Then extend it by creating a PilotJob, TruckDriverJob and so on.

Personally, I tried following Shoebill standarts(from various examples) as much as possible. This is the files and their purpose in my Job module.

JobDao.java an interface for all saving, loading, etc.
JobManager.java registers and handles all the relevant events(for example loading jobs once gamemode is initialized).
Job.java an interface that defines things ALL jobs must have
JobCommands.java - the commands

That's my recent design, but since the my jobs got even bigger so now I have a different package for each job and the JobManager creates each of those managers.

I pass the eventManager to my JobManager from my main, onEnable.
Reply

How does the command priority(NOT command manager) work?

My task is various "/v thing" commands, but if there's no command I want to show help.
Код:
 commandManager.registerChildGroup(vGroup, "v");
 commandManager.registerCommand("v", new Class[]{String.class}, null, null, (short)-1000, false, V_HELP_HANDLER, null, null, null);
I tried both positive and negative priorities for the second command, no change. The second one is executed always. I do not change any priorities in the "vGroup" group commands.
Reply

@dusk:

The command entries are sorted by it's priority (the higher the priority, the more likely it is that this command will be tested and execute before others). I think I know what you are trying to accomplish, and I am not sure if this is possible with the current logic that is used in shoebill-common. I will try it myself right now, and will edit this post to give you feedback.

//Edit: Ok, I had to add some code to detect empty command calls for groups. I pushed an update for the shoebill-common package. You can take a look at the build here: http://ci.gtaun.net/job/shoebill-common/154/

Now, you can make help messages for CommandGroups like this:
Код:
        CommandGroup commandGroup = new CommandGroup();
        commandGroup.registerCommands(new TestGroup());
        commandGroup.setEmptyCommandHandler((player, commandGroup1) -> {
            player.sendMessage(Color.RED, "* This is my help message!");
            return true;
        });
        commandManager.registerChildGroup(commandGroup, "test");
If you return true in the emptyCommandHandler, the further execution of the command will be aborted (that's most likely the best case in this scenario). If you return false, the command will continue to execute which will most likely fail.
Reply

Nice! Thanks a lot for this. While we're on the subject, would it be able to add default handler aswell?

The empty handler is only one part of what I'm trying to achieve. Let's say the command "/v" has two options "list" and "get". So if the user enters only "/v", the empty handler gets called and that's great. But what if the user enters "/v somethingthatsnotdefined". This is what I was trying to achieve with my low-priority "/v String.class" command.
Reply

@dusk: I will take a look at this problem when I got a little bit more time, maybe tomorrow.
Reply

Also could CommandGroup get a "setUsageMessageSupplier" that would only be triggered when a command from that command group is called?

EDIT: I just noticed that usage messages are set per command manager, not per command.


EDIT2: I did not test this on a clean gamemode, but it seems VehicleDeathEvent does not get called, and VehicleParam methods setBonnet and setBoot do not persist, if you set it and retrieve the value it has not been changed, no visual effect either.
Reply

@dusk: I am pretty sure that the VehicleDeathEvent is working, because I am using it in my game mode myself. I looked at the .setBoot and .setBonnet problem but I couldn't find any problem. Are you sure that your vehicle supports these options and are you setting them according to the sa-mp.com wiki (https://sampwiki.blast.hk/wiki/SetVehicleParamsEx)?

//Edit: I pushed an update for the usageMessageSupplier problem. It would be nice if you could test it a little bit deeper than I did, because it might be experimental right now (http://ci.gtaun.net/job/shoebill-common/).

Here is a full example (I also renamed the notFoundHandler):

PHP код:
        commandManager = new PlayerCommandManager(getEventManager());
        
commandManager.registerCommands(new AdminCommands(), new Commands(getEventManager(), commandManager));
        
CommandGroup commandGroup = new CommandGroup();
        
commandGroup.registerCommands(new TestGroup());
        
commandGroup.setNotFoundHandler((playercommandGroup1command) -> {
            
player.sendMessage(Color.RED"* This is my message!");
            return 
true;
        });
        
commandGroup.setUsageMessageSupplier((playerprefixcommand) -> {
            return 
"Hello! This is not the default handler :)";
        });
        
commandManager.registerChildGroup(commandGroup"test");
        
commandManager.installCommandHandler(HandlerPriority.NORMAL); 
Reply

There is again a problem with the @BeforeCheck
The boolean function isn't being called.
Reply

Can you show me your @BeforeCheck function?
Reply

Код:
@BeforeCheck
    public boolean checkPlayer(Player p) {
        System.out.println("Called");
        if(!CPlayer.array[p.getId()].isAdmin(Player.Admin.DEVELOPER)){
            p.sendMessage(Color.RED, "» Access denied");
            return false;
        }
        return true;
    }
Reply

Your BeforeCheck has to conform to a specific signature that is currently not matching with your method's signature. Take a look at the example: https://github.com/Shoebill/example-...tCommands.java

Your method should look like this:
PHP код:
@BeforeCheck
public boolean checkPermission(Player pString cmdString params)
{
    
//Return true or false

Reply

Thank you, I will test but I am wondering why it was working before :S
BTW I'll test a blank gamemode because seems the reloader plugin isn't working, I'll update this post
Reply

I have problems with textdraw string characters.

I have found the problem, in JniFunctions.cpp there are some functions that uses getStringUTFChars and others that uses getStringChars and decode them.

Functions that works bad are: TextDrawSetString, TextDrawCreate (these ones uses getUTFChars instead of getChars)
Reply

@lucesita what is the problem? I've used both functions and had no problems with them.
Reply


Forum Jump:


Users browsing this thread: 22 Guest(s)