simon816 / ComcraftModLoader

Comcraft Mod Loader is a mod to Comcraft that allows multiple mods to be installed at once
http://www.simon816.com/project/comcraftml/downloads/
GNU General Public License v3.0
15 stars 4 forks source link

Runtime error when I try to run my mod #17

Closed nikp123 closed 9 years ago

nikp123 commented 9 years ago

I was making a mod that changes the hexadecimal value of the background and made a day/night cycle.Is it my mistake or the modloader. Error Description (at Runtime , it has compiled without a warning): Error at line 1 (pc:0xa): <- Probably a register ReferenceError: java.lang.NullPointerException default.package.menu

And here's the source (only one file menu.cmod):

Console.log("Comcraft Trainer is Activated!")   //Notify that the mod is loaded (will add features later)
var day = 0                                                       //Day integer (gonna make it editable in command)
var bg = 0xFF000000                                       //Background Hex Value
while(isGui(InGame) == true){                          //Check if inGame is true then make an infinite loop
    if(day <= 256){                                         //Loop which will brighten the day
        bg += 0x0101
        day++
        setColor(bg)                                    //Set the color
        Sleep(1000);                                   //Sleep for a second then continiue
    }else if(day <= 356){                               //This loop just waits
        day++
        Sleep(1000);
    }else if (day <= 612){                              //This loop darkens the day
        bg -= 0x0101
        day++
        setColor(bg)
        Sleep(1000);
    }else {
        day = 0                                           //And when it's done (do it again)
    }
}
simon816 commented 9 years ago

Hi, it looks like you are not using the API correctly. You may want to take a look at the examples to get a better idea of how to use it. Also be sure to look at the docs

The exact reason why you're getting a NPE is because the functions you're using don't exist. The compiler does not check for these things so you cannot rely on that unfortunately.

Also, the mod loader is not multithreaded so your while loop will actually block the game from running.

I am no longer working on CCML (has been about a year since the last commit), but you're welcome to create a Pull Request for a threading/scheduler API if you so wish :)

nikp123 commented 9 years ago

So can I use something like SystemCurrentTimeMillis to get the time instead of Sleep to get the mod working. (I learned it on Android ;) And can I change the background of the game in that way.

simon816 commented 9 years ago

The Mod API is based on events, similar to web browser JavaScript.

The first thing you need to do is add a listener for the Render.Init event. The event payload is the background object. You then need to listen to the screen change event, Comcraft.displayScreen and check whether it's the screen you're looking for, InGame

However, there is no scheduler API so you'll have to use a hack to get that to work. I just had a quick look at the API and you may be able to use to Game.Player.updateEntityMove event as a kind of tick event, good luck!

Here's an example based off what I've described.

var background = null;
EventHandler.bindEvent('Render.Init', function(bg) {
    background = bg;
})

var color = 0xFF000000;
EventHandler.bindEvent("Comcraft.displayScreen", function(screen) {
    if (!screen.isGui('InGame') || background == null) {
        return;
    }
    // Do something with background here
    background.setColor(color);
    color += 0x0101;
})
nikp123 commented 9 years ago

Did I get this right? 1.You break in Render.Init that contains the background color and make a variable for it 2.And you check whenever comcraft is in game (so js is object orianted after all) ,if not or background is null retry. 3.In here i should make a hack for timer 4.Update bg color

nikp123 commented 9 years ago

This works for javascript: var d = new Date(); Will it also work for MINIJOE?

nikp123 commented 9 years ago

I meant in this way:

var background = null;
var cs,s,day;
EventHandler.bindEvent('Render.Init', function(bg) {
    background = bg;
})

var color = 0xFF000000;
EventHandler.bindEvent("Comcraft.displayScreen", function(screen) {
    if (!screen.isGui('InGame') || background == null) {
        return;
    }
    var time = new Date(); 
    if (s == null || cs >= s){
        s = time.getSeconds();
        if(day <= 256){
            color += 0x0101;
            background.setColor(color);
        }else if(day <= 456){
            return;
        }else if(day <= 712){
            color -= 0x0101;
            background.setColor(color);
        }else if(day <= 800){
            return;
        }else{
            day = 0;
        }
                day++;
    }else{
        cs = time.getSeconds();
    }
})
simon816 commented 9 years ago

Date is implemented in minijoe, you can see the source code for it in JsDate.java The code you've posted will only work when the current screen is changed (The event Comcraft.displayScreen is only fired when changing screen) I suggest doing the actual changing of the color when Game.Player.updateEntityMove is fired. You could create a simple boolean variable to indicate whether the time should be ticking (hint: when the GUI InGame is active)

nikp123 commented 9 years ago

I don't want my mod to depend on players movement so I don't need your suggestion. But creating a boolean is a good idea so I'll try that to get the mod working. Thx :D

simon816 commented 9 years ago

I suggested that event because it is the only one that fired every in-game tick. As the docs state,

Fired continually (every game tick) to update the player's movement.

You'll need to use this in order to update the time.

Based on the code you've posted, I came up with this

var background = null;

EventHandler.bindEvent('Render.Init', function(bg) {
    background = bg;
})

var color = 0xFF000000;
var tickCount = 0;
var timeOfDay = 0;

EventHandler.bindEvent("Game.Player.updateEntityMove", function() {
    if (tickCount++ % 10 != 0) {
        return;
    }
    timeOfDay++;
    if (timeOfDay <= 250) {
        color += 0x0101;
        background.setColor(color)
    } else if (timeOfDay > 450 && timeOfDay <= 700) {
        color -= 0x0101;
        background.setColor(color)
    } else if (timeOfDay > 800) {
        timeOfDay = 0;
    }
})

You don't even need to check for the gui InGame because the tick event is fired whenever the game is in play. (Just as well because the screen.isGui('InGame') didn't work when I tested it!)

The speed at which the time changes is determined by the statement if (tickCount++ % 10 != 0) this means there are 10 ticks for every in game second.

Anyway, there's enough information here for you to write the mod, closing this issue now.