Getting started and mysteriously failing

54 views
Skip to first unread message

Nathan Peirce

unread,
Jan 15, 2018, 1:05:24 AM1/15/18
to ScriptCraft - Scripting Minecraft
Hi.

I've been banging my head against my desk for a few weeks now trying to figure out making mods in ScriptCraft, mainly here recently:

I have a lot of coding experience, some familiarity with java and javascript, and I like learning, so I figured the learning curve for ScriptCraft wouldn't be _too_ painful, and I love the idea, but it's been a bit of a nightmare.

I managed to get a SpigotMC server going, ScriptCraft loaded, and a simple mod running successfully which uses and affects the in-game chat.
I've also got a working listener for block breaking, and I can change the block type that's being dropped and get the player who broke it.
I also have a working listener for mob death, and I can route code execution based on what type of mod died.

So I know ScriptCraft is working in some fashion.

I'm trying to add or change a mob's drop, get the player who killed the mob, or even just spawn an item at the dying mob's location rather than having the mob drop it.

I see there's no .getPlayer() or .player for the listener events.entityDeath(function_name); so I'm at a loss to know who killed the mob.

For adding or changing the drop...
I see .getDrops() returns List<ItemStack> but I don't see a .setDrops().
Finally I realized that the item stack returned is probably a pointer to the stack that can itself be altered and will then drop, regardless of having been gotten by .getDrops().
To that end, I see List has .add and I see ItemStack has .setType(Material type) and .setAmount(int amount).

So putting that all together, at first I thought maybe...

List<ItemStack> new_drop = {new ItemStack(Material.DIAMOND_BLOCK, 1)};
event.getDrops().add(new_drop);

I've tried a lot of variations and looked up JavaScript in more depth, but I guess I haven't hit on the right syntax.

This doesn't work and stops my mod in its tracks...
var player = getPlayerObject();
...and...
var player = player.getWorld();
var villager = world.spawnCreature(player.getLocation().add(1,0,0), org.bukkit.entity.EntityType.VILLAGER);
...which were adapted from the quest mod, which was recommended by the ScriptCraft website.

The quest mod in its entirety doesn't do anything when I add the file next to my mod's file, so maybe that's just due to being out of date code.

From the ScriptCraft API...
items.book(); // returns org.bukkit.Material.BOOK
...but I can't even assign it to a variable without breaking my mod.
var a_book = items.book();

Not sure if my problems are due to references being for old version of ScriptCraft, or if ScriptCraft documentation is out of date, or if I installed something wrong during setup maybe so ScriptCraft is only half working, or am I just not getting it?

Thinking about it, I'm pretty much burned out on ScriptCraft at this point, but I think it would be good for the developers/community if a way could be found to fill this gap so others don't fall in.

Thanks in advance.

HTH.

-Nathan

Walter Higgins

unread,
Jan 15, 2018, 4:47:47 AM1/15/18
to ScriptCraft - Scripting Minecraft
Hi Nathan, I'll try to respond in detail later today or tomorrow.

Landru 27

unread,
Jan 16, 2018, 10:18:42 PM1/16/18
to ScriptCraft - Scripting Minecraft
Hi Nathan -

Here is a demonstrator script that addresses much of what you asked about entityDeath and drops:

//  import ScriptCraft modules
//
var utils = require('utils');
var events = require('events');
var items = require('items');
var inventory = require('inventory');

function reportDeathAndDropDiamods(event) {
   
var killed = event.getEntity();
   
var player = killed.getKiller();

   
var playerlocation = player.location;
   
var playerworld = playerlocation.world;

    echo
(player, 'the player ' + player.name + ' killed a ' + killed.getType());

    playerworld
.dropItem(killed.getLocation(), new Packages.org.bukkit.inventory.ItemStack(org.bukkit.Material.DIAMOND, 3));
}

events
.entityDeath(reportDeathAndDropDiamods);

I tested this and it works on my recent (less than a month old) installation of a Minecraft/Spigot/ScriptCraft server.  So if this does not work on your setup, then you are probably right about some component being out-of-date, or mismatched to other components.

This does not do everything you asked about (e.g., the entity still drops it's normal drops, too), but I'm hoping that this provides enough insight to get you back on track.

I'm fairly new to ScriptCraft, myself, and I found that working with the Bukkit API does involve some indirect approaches.  But I've also found that the more one works with it, the more one gets used to its "philosophy".

If you do figure out how to suppress an entity's normal death drops, please post a follow-up here -- I'd be very interested in how to do that.

Thanks, and HTH.

- Andrew

Nathan Peirce

unread,
Jan 17, 2018, 12:34:51 AM1/17/18
to ScriptCraft - Scripting Minecraft
Hi, Andrew.

You're a gentleman and a scholar.

Packages! Packages! Packages.org.bukkit.inventory...!
How have I spent so much time scouring every bit of ScriptCraft material I could find and not run across that?!?
I tried so many permutations, for nothing. Nothing, I tell you. The humanity!
Well, never mind that. All's well that ends well. You've helped me put some nice closure on a bad experience and I appreciate it.

I've moved on to Forge, using Java to write mods directly, and so far it's been vaguely reasonable so I'll probably stick with that at least until I get a sense of the lay of the land with server mods. (Since most resources seem to focus on single player whereas ScriptCraft pleasantly is designed to work on the server in the first place, so maybe I'll be back.)

Even so, I'm very grateful for your kind reply and to show that gratitude I concocted this with your magic ingredient (by which I mean, Packages!), to show you the coolest way I could think of how to suppress an entity's normal drops, and we can even abandon the artifice of world-method drops while we're at it, if we want to, and let the normal drop process proceed as nature intended (but with our little alteration in place).

OMG it's all so easy now. (*cry*)

function zombiesDropDiamondsNotRot(event) {
//  server.broadcastMessage('Something died...');
  var dead_entity_type = '' + event.getEntityType();
    server.broadcastMessage(a_or_an(dead_entity_type, 'A', 'An') + ' ' + dead_entity_type.toLowerCase() + ' died!'); 
  if (dead_entity_type == 'ZOMBIE') {
    var randomAmount = Math.ceil(Math.random() * 3) - 1; // evaluates to 0-2, same as amount of Rotten Flesh zombies are known to drop.
    event.drops.clear(); // removes all of the mob's normal items from this drop event.
    var replacementStack = new Packages.org.bukkit.inventory.ItemStack(org.bukkit.Material.DIAMOND, randomAmount);
    event.drops.add(replacementStack); // adds the new replacement stack to the current drop.
  }
}
events.entityDeath(zombiesDropDiamondsNotRot);

function a_or_an(str_expression, str_a, str_an) {
  //Default values and data types:
  var str_return = '';
  if (typeof str_expression === 'undefined') {str_expression = '';}
  if (typeof str_a === 'undefined') {str_a = 'a';}
  if (typeof str_an === 'undefined') {str_an = 'an';}
  str_expression = '' + str_expression
  //Choose between 'a' and 'an':
  if (str_expression.length > 0) {str_return = (char_is_vowel(str_expression.charAt(0))?str_an:str_a);}
  //Return:
  return str_return;
}

Thanks again.

-Nathan

Landru 27

unread,
Jan 17, 2018, 1:31:48 AM1/17/18
to ScriptCraft - Scripting Minecraft
Ah, I see:  use .clear() and .add() to operate on the List object itself, rather than trying to affect the item-drop attributes of the (kind of) Entity.  Clever!

I stumbled upon the Packages object / reference looking through the source code of the plugins (and modules, and libraries, which are just other .js scripts) that come with ScriptCraft.  And, another member of this Google Group clarified for me in reply to a post of mine where that comes from:  nashorn, which forms the bridge between Java and JavaScript, makes the Packages object available.

The ScriptCraft API in turn has shortcuts that make it less necessary to use 'Packages.blah.blah.blah' everywhere.  These are both handy as an API, and instructive as examples of how to make full use of the Bukkit API.

- Andrew
Reply all
Reply to author
Forward
0 new messages