Posts by Miwarre

    So far, I found that enumerating installed plug-ins is possible but involves assumptions and caveats. First of all, enumerating is only possible by ID, as it is not possible to know in advance the names!


    1) Assumption: as far as I can tell, plug-in ID's are always sequential, i.e. in increasing order and without 'holes'. Can this be documented and 'cast in stone'?


    2) Caveat: ID's do not necessarily start at 0; if "reloadplugins" has been used (and possibly under other circumstances too), plug-in ID's may start with any integer. This requires a first loop to find the first ID and a second loop to iterate on the ID.


    As said above, it is possible to do it; it would be nice however if the process could be streamlined somewhat, for instance by providing a Plugin.getAllPlugins() method returning an array (or ListArray or whatever) of all installed plug-ins.


    Thanks!

    A plug-in which displays a menu of installed (and conforming!) plug-ins to access their GUI in a simple and constant way.


    No need to remember the command(s) of each plug-in! Just the command to call the Central up.


    Version 0.2.0:


    - New to 0.2.0:


    *) Adapted to the latest updates to RWGui.


    -Features:


    *) GUI-only: everything is done via a GUI (of course!).


    *) There is only one chat command (default /pc, but it can be configured in the plug-in settings.properties) which displays, in alphabetical order, a list of all installed plug-ins which conform to a simple API:


    *) The plug-in looked for can be selected with a mouse click and its GUI will be displayed.
    ____________________


    Important - Important - Important - Important:


    In order to work, the plug-in requires the RWGui back-end plug-in ver. 0.5.0 available in this thread.
    ____________________


    - Commands


    There is only one command: /pc (configurable in the plug-in settings.properties) which shows the above main menu.


    Installation


    *) Extract the files in the ZIP placing the whole plugincentral folder into the plugins folder of RW (if the plugins folder does not exist, just create one). The resulting hierarchy shall be:


    Code
    ── RisingWorld
    ├── plugins
    │ ├── plugincentral
    │ │ ├── locale
    │ │ ├── plugincentral.jar
    │ │ └── settings. properties


    *) If it is not already installed, the GUI plug-in available in this thread shall also be installed.


    Making my plug-in to appear in Plug-in Central list


    Only two rather simple methods have to be added to a plug-in to make it compatible the Plug-in Central:


    public String getPublicName() which returns a (constant) string with a human readable name for your plug-in.


    public void mainGui(Player player) which displays the main entry point for your plug-in to player (in practice, this method does what your plug-in already does in response to some specific player command).


    Sample code to add to a plug-in to conform to the proposal:


    The existing chat command to access the plug-in can remain and use the same code:

    Code
    @EventMethod
    public void onPlayerCommand(PlayerCommandEvent event)
    {
    String[] cmd = event.getCommand().split(" ");
    if (cmd[0].equals("/myPluginCommand") )
    mainGui(event.getPlayer());
    }


    Notes:
    *) The code does not require any additional logic to be implemented in the plug-in (it should already have code to display some kind of user interface to the player)


    *) It is not necessary to remove anything from existing plug-ins: all existing features can remain and work as previously.


    *) It is not necessarily limited to GUI-based plug-ins; also chat-based plug-ins can benefit from it: there is no limitation on what the main user interface method can do, each plug-in decides: it might be a super-dooper completely GUI panel, it might be just a summary of chat commands in the chat itself or anything in between.


    If anybody has ideas for improvement, please post them here!


    Open points and known issues


    *) None at the moment, but bugs may well exist! I did my best but foreseeing all the possible use cases and contexts is hard. Post here bug reports, with specific steps to replicate the issues and I'll try to correct them.


    I really need steps or instructions to replicate the problem on my PC or I cannot fix it!

    Sounds interesting!


    About the GUI, if you are interested, we could work together to extend my attempt at a GUI back-end plug-in providing ready-made and interactable "dialogue boxes" to other plug-ins, so that it is not necessary for everybody to re-invent ALL the wheels.


    I am already using in most of my plug-ins, so it works; it only does what I needed so far, though.


    If you are interested, we can discuss further here or in PM.


    For example, 1 blueprint can save any volume/# of objects. But it will take 1 blueprint for every 8x8x8 or 100 objects (just an example)

    This could make sense, but it should clear in advance how many blueprints a saved one would consume on pasting (for instance, it could be an info line in the journal blueprint list).

    Sometime, it is convenient to either un-set a player attribute (and to be able to test for it to return null) or to remove the reference to an object stored in an attribute and allowing it to be garbage collected when no longer used (particularly a non-primitive object type, like a GuiElement).


    There are work-around, of course: a primitive type can be set to a specific, "none", value (e.g., with a Boolean or an Integer); an attribute supposed to contain a complex type can be set to a Boolean "false" and checked for being null or an instance of Boolean, and so on. However, these are ad-hoc solutions, obfuscating the code and increasing maintenance complexity.


    Currently, it is not possible to set an attribute to null, which would be the easiest and clearest solution.


    The request is then to either:


    1) allowing to set an attribute to a null value (from the consumer perspective, it is irrelevant if this results in the attribute being physically removed form the attribute collection or in it remaining there and being assigned an actual null value, as long as getting it back returns null)


    OR


    2) allowing to un-set an attribute via a specific Player.unsetAttribute(String attributeName) method.



    I hope the use cases are clear enough. If not, I could elaborate them further.

    Thanks for the reply. I understand the point about .equals() and I hope the causes for the oddities with events can be found too.


    The whole is not OVERLY important, as it is always possible to achieve the same results with a non-sub-classed class which hosts an Area field in itself. Sub-classing is surely cleaner and possibly lighter, though.

    Thanks for the reply. I'll check again with all the possible combinations of the three flags involved and, if I find something which does not match your description, I'll provide a full test case.


    About the of setEditable(false) and setClickable(true) combination, I suggest it to be implemented, at least as long as a GuiLabel cannot be (easily?) be made to look like a GuiTextField to show a datum which has been entered (for instance choosing in a list) but not directly editable.


    Possibly it isn't a BIG change?

    Hmmm... in line 6 of plug-in A, the attribute value is set to an Integer and in line 1 of plug-in B the retrieved Integer value is cast to a String.


    In fact, I have not clear if such a cast makes sense. Maybe, it is supposed to work, but to be surer, I would retrieve the value as an Integer and either use Integer.toString() in line 3 of plug-in B to convert it to a String or, if you feel lazy, rely in the implicit conversion:


    Code
    Integer value1 = (Integer)player.getAttribute("PlayerTestMoney");
    player.sendTextMessage("Show the Value:" + value1.toString());

    OR

    Code
    Integer value1 = (Integer)player.getAttribute("PlayerTestMoney");
    player.sendTextMessage("Show the Value:" + value1);

    I would prefer to first; also, chances are that sooner or later I'll need a more elaborate String.format() in the message to the player.


    EDIT: Oh well, cross-posting...! 8o

    I am facing unexpected results (at least unexpected by me!) when using a sub-class of the net.risingworld.api.utils.Area class:


    1) The PlayerEnterAreaEvent fires repeatedly while the player moves within the area without leaving it


    2) The PlayerLeaveAreaEvent never fires


    3) The Area.equals() methods returns false even when the two objects involved in the test are physically the same object.


    The attached, small, sample plug-in defines a sub-class of the Area class, uses an instance of it to test several events and shows the issues described above.


    Am I wrong in expecting that an instance of a sub-class of Area should behave as an instance of Area itself for the common, non-overriden methods?

    Files

    • Test.java.zip

      (883 Byte, downloaded 240 times, last: )

    Sorry, I cannot understand the logic:


    *) the command you quote (p.sentTextMessage(""+"THE ATTRIBUTE"), once capitalisation corrected) is not a test and does not return anything
    *) the effect of this command is just to write the constant string "THE ATTRIBUTE" in the player chat, which tells little about what is happening.


    - How the attribute is written in plug-in A?
    - How the attribute is read back in plug-in B?

    @jackripper: I see, as described in the list of commands a the beginning of the thread and in the help sub-command, the command to create a new level is:


    /elev newlevel <elevalor_id> <level_number>


    Assuming you are dealing with the first elevator created -- which has an ID of 1 -- and with the floor number 2 of this elevator, the command will be:


    /elev newlevel 1 2


    With a different elevator, the first number (1 in the example) will be different and for a different level (or floor) the second number (2 in the example) will be different.


    You are right that the message displayed on the screen when starting the area selection process, tells about a "createlevel" sub-command; which was a previous version. I apologise for the inconsistency and I am surprised nobody noticed it so far. As it is unlikely that the LUA script will be updated (I am rather porting it to Java), I'll add a note to the description at the start of the thread.

    Setting a GuiTextField element as clickable with GuiTextField.setClickable(true) seems to have no effect: clicking on the element does not generate any PlayerGuiElementClickEvent event.


    This is the specific code I am using for the element (it belongs to a sub-class of the GuiPanel class containing several other child elements):


    Code
    text= new GuiTextField(NAMETEXT_XPOS, OWNER_YPOS, false, NAMETEXT_WIDTH, TEXTENTRY_HEIGHT, false);
    text.setPivot(PivotPosition.TopLeft);
    text.setBorderThickness(1, false);
    text.setBackgroundPreset(1);
    text.setClickable(true);
    text.setEditable(false);
    text.setListenForInput(false);
    addChild(text);
    player.addGuiElement(text);

    I tried with various combination of setEditable(false/true) and setListenForInput(false/true) with no difference. The field IS shown and, if set to editable, can be edited and generates PlayerGuiInputEvent, so I presume the code is basically correct.


    The specific use case is to simulate a dropdown / combo list, where the text of the element is not directly editable but clicking on it shows a list to choose from. I can use a work-around using a GuiLabel for the text and a button to show the list, but the visual result is not as clean and evident as it could be.


    Am I overlooking something or there is a bug indeed?

    3) Snail Mail: You know how Romans used to keep their vast Empire in the know without technology? Do it yourself via snail mail[...]

    I like the idea of snail mail; user-wise is relatively simple to implement in a rather meaningful way. A "post box"-like craftable item, which only certain players (admins?) can craft to simulate the fact that a post box by itself does nothing and requires a complex back-end network in order to work.


    Any user can go to the post box and "post" a message / letter. After a time proportional to the distance, the 'letter' would be 'dropped' in the recipient chat window. While potentially amusing, it is not strictly necessary to simulate the details of what happens in between.


    Variations:


    - 'letters' may be dropped in a specific user mail box, rather than in the chat, with a history / log of received letters.
    - sending may have a cost ("stamp"); as long as the game does not have a built-in currency, it may be in resources
    - there might be a 'broadcast' mode, toward a specific post box and the 'letter' would be received by all users within a certain radius of the destination post box (possibly with a higher cost).
    - it might totally supersede any world-wide chat; the today chat would only be 'local', i.e. within a certain radius from the speaker.


    As I have already said in several occasions, I do not like the idea of implementing a technology progress in the user play flow (including techniques for communication). The idea might be appealing on paper, but I am convinced that it does not suits the mechanics of the current MP model (and, of course, mail and communication in general does not make sense in single player).


    P.S.: The Roman Empire relied on the same communication means used by any other empire or largish country since early antiquity up to XIX century. They 'simply' organised and managed those means somehow better (and not always neither anywhere).

    Hi community,
    This plugin allows every player to set his unique home point and to port to it.

    Just out of curiosity and to know more of the needs of other users, why the GPS plug-in was not suited? It does everything this plug-in does and more, all without the need to remember additional, structured chat commands...