// random number
/* Much better random function than one in video (I still learning :P) */
//init tab
var random_f = {
r_f : function (array) {
var r_number;
r_number = Math.floor(Math.random() * array.length);
return array[r_number];
}
}
npc.setTempData("random_f",random_f);
/* Then in your interact tab put the array you want to choose from (can be any length and can 'weight' item by repeating in the array)
var i_array=[], item_n; */
//////////////////////////////////////
if(x == undefined)
var x = 0;
switch (x) {
case 10:
npc.say("yo, what up");
x = 0;
default:
x++;
}
//switch command for delay//
currentStep = npc.getTempData("ActionStep");
switch (Number(currentStep)) {
case 0:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 1:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 2:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 3:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 4:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 5:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 6:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 7:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 8:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 9:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 10:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 11:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 12:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 13:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 14:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 15:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 16:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 17:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 18:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 19:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 20:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 21:
npc.setTempData("ActionStep", 0);
break;
}
//+++++++++++++++++++++++++++ kill one the other changes
//update npc a
if (world.getTempData("npc_one")==1) {
npc.setMeleeResistance(1);
npc.setArrowResistance(1);
npc.setKnockbackResistance(1);
npc.setExplosionResistance(1);
world.removeTempData("npc_one");
}
//killed npc b
world.setTempData("npc_one",1)
///++++++++++++++++++++++
if (player.hasReadDialog(##)) {
world.spawnClone(npc.getX(), npc.getY(), npc.getZ(), 1, "ABC");
/*I usually unread it here so you dont have to delete the dialog from the player data later if you want to run it again*/
npc.executeCommand("/noppes dialog unread @p ##");
npc.despawn();
}
// spawn new on death
world.spawnClone(npc.getX(), npc.getY(), npc.getZ(), 1, "Wate");
npc.despawn();
// NEW API
var clicked = 0;
function interact(event){
clicked++;
event.npc.say(clicked);
}
Something I has wanting to finish for a while - making NPC work with minecarts - I really like Railcraft mod but it will be in 1.7.10 for some time it looks like so I made this in 1.8.
So now I can get to some questions I saw on the forum.
Hey daottoad. Love your work. I've been following the npcs thread for a while and you've given me some useful advice.
I am currently working with 1.8.9. I have some complicated things I would like to do with scripting, but I am still very new and could use a little help with the simple stuff. For my first script, I would like to spawn a cloned npc into the world (presumably using spawnClone), by standing in a certain spot while a quest is active. What would be the simplest kind of script I could write to accomplish this? I've been educating myself on classes and modifiers, but I am still a little confused on how to write everything out properly using the customnpcs API.
Hey daottoad. Love your work. I've been following the npcs thread for a while and you've given me some useful advice.
I am currently working with 1.8.9. I have some complicated things I would like to do with scripting, but I am still very new and could use a little help with the simple stuff. For my first script, I would like to spawn a cloned npc into the world (presumably using spawnClone), by standing in a certain spot while a quest is active. What would be the simplest kind of script I could write to accomplish this? I've been educating myself on classes and modifiers, but I am still a little confused on how to write everything out properly using the customnpcs API.
Simple is very relative - I am still struggling with the new scripting format, so something that would be simple in 1.8 is not very straightforward for me - YET. But the best way to do this I think would be with a scripted block when you walk over it, then it will see if you have the quest and will spawn a NPC - think this would work for you?. I will work up and example and see what you think.
Thank you, I appreciate it, and that will certainly work!
In all honesty, I would like to make it so a certain sequence of places need to be visited during the quest before the script will work, but I think I could use command blocks to do this. The second-to-last place would spawn a block near the script block that it could test for, in addition to a player being nearby. I'll probably try to figure that script out on my own first, though (will post it if I succeed.)
It does seem that 1.8 scripting is very different. I haven't succeeded in converting any of my old ones yet. Normally to spawn an npc I would use /noppes clone spawn, but that command seems to have vanished for now =).
I hadn't thought of using tempdata to reset scripts. That makes things much more streamlined. I appreciate you posting these scripts. Not only are they useful for what I had in mind, but they also provide a good example as to how the new API works. I will be trying more complex scripts as needed, and keeping up with this thread.
Awesome vid! I'm assuming that was a quick skin change script with time parameters. I imagine it's a little time-consuming to do that even on a small scale.
Anyway, I'm back with what I thought was a simple script.
function init(event) {
event.npc.world.getTempdata().put("WepSwi",1);
}
function damaged(event) {
if (event.npc.world.getTempdata().put("WepSwi") == 1) {
event.npc.setLeftHand(getDisplayName("Iron Sword"));
event.npc.say("You’ll pay for that!");
event.npc.world.getTempdata().put("WepSwi",0);
}
}
function tick(event) {
if (event.npc.getHealth() == event.npc.getMaxHealth()) {
event.npc.setLeftHand(getDisplayName("Book"));
event.npc.world.getTempdata().put("WepSwi",1);
}
}
I am having trouble with definitions though. After troubleshooting it for a while, I couldn't manage to get past this error:
Wed Sep 07 11:46:32 PDT 2016 tab 1:
javax.script.ScriptException: TypeError: noppes.npcs.api.wrapper.NPCWrapper@3b71df6f has no such function "setLeftHand" in <eval> at line number 15
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:389)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)
at noppes.npcs.controllers.ScriptContainer.run(ScriptContainer.java:100)
at noppes.npcs.entity.data.DataScript.runScript(DataScript.java:62)
at noppes.npcs.EventHooks.onNPCTick(EventHooks.java:93)
at noppes.npcs.entity.EntityNPCInterface.func_70071_h_(EntityNPCInterface.java:258)
at noppes.npcs.entity.EntityCustomNpc.func_70071_h_(EntityCustomNpc.java:35)
at net.minecraft.world.World.func_72866_a(World.java:1860)
at net.minecraft.world.WorldServer.func_72866_a(WorldServer.java:699)
at net.minecraft.world.World.func_72870_g(World.java:1829)
at net.minecraft.world.World.func_72939_s(World.java:1661)
at net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:544)
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:701)
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:605)
at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:152)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:481)
at java.lang.Thread.run(Thread.java:745)
Caused by: <eval>:15 TypeError: noppes.npcs.api.wrapper.NPCWrapper@3b71df6f has no such function "setLeftHand"
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:106)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:71)
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154)
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253)
at jdk.nashorn.internal.scripts.Script$Recompilation$161$320A$\^eval\_.tick(<eval>:15)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:642)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:199)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383)
... 16 more
The script is supposed to have the npc draw a weapon in its right hand and make a threatening statement if attacked. It is supposed to sheath the weapon and reset the script once its health returns to full. It's meant to work if the npc has health regen, but no combat regen. There are probably other problems with the script too.
Hmm. That makes sense. I had originally put NPCInventory in that spot but it was of course undefined.
What is the difference between a method being under the itemstack interface (like getDisplayName) and simply having Itemstack as a modifier (like createItem)? I thought that all IItemstack methods would be under that interface, so I didn't initially look for createItem in IWorld.
Hmm. That makes sense. I had originally put NPCInventory in that spot but it was of course undefined.
What is the difference between a method being under the itemstack interface (like getDisplayName) and simply having Itemstack as a modifier (like createItem)? I thought that all IItemstack methods would be under that interface, so I didn't initially look for createItem in IWorld.
I really don't know. I have had quite a lot of experience looking at the old api so I sometimes know where stuff can be.
I'm really hoping you intended on keeping this thread going as I have a question. I have added custom sounds to the customnpcs and they work fine when using the wand. The problem is I want to script the sounds in but I do not know how to call the sound file from the library. I assume that I need to use the executeCommand function and minecraft's playsound command but Minecraft disregards the sounds folder for custom sounds (the ones I add not the ones for mods) mostly because I am pointing the file path to the mod's folder like this: playsound customnpcs:mysound @p 24 68 -14 2 1. I know that is the wrong file path but I don't know where to point it otherwise and was hoping it would work. Is there a customnpc function that calls for playing a sound? I looked and couldn't find it. Thanks for any help you can give.
This works in 1.10 - the playsound command might have changed in other versions - sounds can be finicky in the sounds.json but if it works otherwise ???
Can find scripting info and ask questions on the "new" (relatively) discord channel https://discord.gg/2jZm88M
I'm using 1.7.10 for the other mods for this map so I am using the tabs. I did get it to work, thank you for the help!
npc.executeCommand("playsound customnpcs.gully_dwarf:gully_laughlow @a 57 65 -49 2 1"); this was the wrong code
npc.executeCommand("playsound customnpcs:gully_dwarf.gully_laughlow @a 57 65 -49 2 1"); this is right, I wasn't sure how to separate the folders in the command code
Do you know the difference in sound when you play it @a vs @p? Is it louder?
Hello
I am start this thread to help with the Custom NPC scripting. I would like to keep thing here simple at first to help people who are new to scripting.
I will be using JavaScript for my scripting although there are other languages available. (like Python)
My Youtube channel
https://www.youtube.com/channel/UC5Ar_nk7O9xGsX3KBM_qxxw
Good source of JavaScript reference:
http://www.w3schools.com/js/default.asp
http://eloquentjavascript.net/
There are of course lots more...
Programs that help:
Notepad++
PSpad
Free JavaScript Editor
And last and most important Noppes API etc.
http://www.kodevelopment.nl/minecraft/customnpcs/scripting
This is a jumble of useful routines which I call my "reference" - and I will work towards cleaning it up and making it a little more understandable.
if (i == undefined)
var i = 0;
i++;
npc.say("times called: " + i);
// do while
do {
text += "The number is " + i;
i++;
} while (i < 10);
/////////////
if(i == undefined)
var i = 0;
i++;
npc.say("times called: " + i);
// for loop //
for (i = 0; i < guests.length; i++) {}
/////////////////////
try {
world.getTempData("fire_orb_list").despawn();
}
catch(err) {
npc.say("not a npc");
}
////////////////////////////
// if getblock position //
if (npc.getBlockX() == 84 && npc.getBlockY() == 78 && npc.getBlockZ() == 124) {}
// cancelled //
event.setCancelled(true);
// killed tab
event.getSource().setExpLevel(event.getSource().getExpLevel() + 10);
// random number
/* Much better random function than one in video (I still learning :P) */
//init tab
var random_f = {
r_f : function (array) {
var r_number;
r_number = Math.floor(Math.random() * array.length);
return array[r_number];
}
}
npc.setTempData("random_f",random_f);
/* Then in your interact tab put the array you want to choose from (can be any length and can 'weight' item by repeating in the array)
var i_array=[], item_n; */
i_array[0]="customnpcs:npcGoldTrident";
i_array[1]="customnpcs:npcIronTrident";
i_array[2]="customnpcs:npcEmeraldTrident";
i_array[3]="customnpcs:npcCursedTrident";
i_array[4]="customnpcs:npcFrostTrident";
i_array[5]="customnpcs:npcDemonicTrident";
i_array[6]="customnpcs:npcMithrilTrident";
i_array[7]="customnpcs:npcBronzeTrident";
i_array[8]="customnpcs:npcDiamondTrident";
i_array[9]="customnpcs:npcStoneTrident"
item_n = npc.getTempData("random_f").r_f(i_array);
npc.setRightItem(world.createItem(item_n,0,1));
npc.say(item_n);
//
/////////////////
var r_number;
r_number = Math.floor((Math.random() * 10) + 1);
if (r_number == 1) {
//
}
if (r_number == 2) {
//
}
if (r_number == 3) {
//
}
if (r_number == 4) {
//
}
if (r_number == 5) {
//
}
if (r_number == 6) {
//
}
if (r_number == 7) {
//
}
if (r_number == 8) {
//
}
if (r_number == 9) {
//
}
if (r_number == 10) {
//
}
//////////////////
random_number = Math.floor(Math.random() * 10);
switch (random_number) {
case 0:
//
break;
case 1:
//
break;
case 2:
//
break;
case 3:
//
break;
case 4:
//
break;
case 5:
//
break;
case 6:
//
break;
case 7:
//
break;
case 8:
//
break;
case 9:
//
break;
}
//////////////////
var r_number;
r_number = Math.floor((Math.random() * 10) + 1);
if (r_number == 1) {
event.setCancelled(true);
}
if (r_number == 2) {
event.setCancelled(true);
}
if (r_number == 3) {
event.setCancelled(true);
}
if (r_number == 4) {
event.setCancelled(true);
}
if (r_number == 5) {
event.setCancelled(true);
}
if (r_number == 6) {
event.setCancelled(true);
}
if (r_number == 7) {
event.setCancelled(true);
}
if (r_number == 8) {
event.setCancelled(true);
}
if (r_number == 9) {
event.setCancelled(true);
}
if (r_number == 10) {
event.setCancelled(true);
}
///////////////////////////////////
//init
npc.setTempData("timer1",world.getTotalTime());
//update
if (world.getTotalTime() - npc.getTempData("timer1") > 6000) {
npc.despawn();
}
////////////////////////////////////////
// dialog control //
if (player.hasReadDialog(141)) {
npc.executeCommand("/noppes dialog unread @p 141");
} else if (player.hasReadDialog(143)) {
npc.executeCommand("/noppes dialog unread @p 143");
} else if (player.hasReadDialog(144)) {
npc.executeCommand("/noppes dialog unread @p 144");
}
// surround entities //
if (npc.getSurroundingEntities(3, 2).length > 0) {
// detect NPC
}
if (npc.getSurroundingEntities(3, 1).length > 0) {
// detect players
}
// toggle //
if (npc.getTempData("toggle") == 0) {
npc.setTempData("toggle", 1);
} else {
npc.setTempData("toggle", 0);
}
// summon
npc.executeCommand("/summon Item ~ ~2 ~ {Item:{id:dye,Damage:8,Count:1,tag:{display:{Name:\"Points\"}}}}");
// place block //
npc.executeCommand("setblock 84 75 124 minecraft:redstone_torch");
// tp
npc.executeCommand("tp @p ~ ~5 ~");
//tp
npc.executeCommand("tp " + player.name + " 123 60 123");
//////////////////////////////////////// deley routine
npc.setTempData("ActionStep",0);
npc.setTempData("stop_attack",1);
//update
if (npc.getTempData("stop_attack") == 0 ) {
var currentStep = npc.getTempData("ActionStep");
npc.setTempData("ActionStep", Number(currentStep) + 1);
}
if (npc.getAttackTarget() != null && npc.getTempData("ActionStep")==20){
npc.setTempData("ActionStep",0);
npc.setTempData("stop_attack",1);
npc.setAttackTarget(null);
}
//attack
npc.setTempData("stop_attack",0);
npc.setTempData("ActionStep",0);
//////////////////////////////////////
if(x == undefined)
var x = 0;
switch (x) {
case 10:
npc.say("yo, what up");
x = 0;
default:
x++;
}
//switch command for delay//
currentStep = npc.getTempData("ActionStep");
switch (Number(currentStep)) {
case 0:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 1:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 2:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 3:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 4:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 5:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 6:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 7:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 8:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 9:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 10:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 11:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 12:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 13:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 14:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 15:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 16:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 17:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 18:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 19:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 20:
npc.setTempData("ActionStep", Number(currentStep) + 1);
break;
case 21:
npc.setTempData("ActionStep", 0);
break;
}
//+++++++++++++++++++++++++++ kill one the other changes
//update npc a
if (world.getTempData("npc_one")==1) {
npc.setMeleeResistance(1);
npc.setArrowResistance(1);
npc.setKnockbackResistance(1);
npc.setExplosionResistance(1);
world.removeTempData("npc_one");
}
//killed npc b
world.setTempData("npc_one",1)
///++++++++++++++++++++++
if (player.hasReadDialog(##)) {
world.spawnClone(npc.getX(), npc.getY(), npc.getZ(), 1, "ABC");
/*I usually unread it here so you dont have to delete the dialog from the player data later if you want to run it again*/
npc.executeCommand("/noppes dialog unread @p ##");
npc.despawn();
}
// spawn new on death
world.spawnClone(npc.getX(), npc.getY(), npc.getZ(), 1, "Wate");
npc.despawn();
// NEW API
var clicked = 0;
function interact(event){
clicked++;
event.npc.say(clicked);
}
function died(event){
clicked = 0;
}
///////////////////
function interact(event){
event.npc.say("Something");
event.npc.timers.start(1, 40, false);
}
function timer(event){
if(event.id == 1){
event.npc.say("Something else");
event.npc.timers.start(2, 20, false);
}
if(event.id == 2){
event.npc.say("Something more");
}
}
As I organize my stuff I will try to post it here in a usable format.
Translated by Google:
It's great that you've decided to create such a forum. I was looking like the Internet. It is only flood.
For example, you can give a spoiler script:
NPC changes the subject in hand, after completing the quest.
Change the object in the NPC hand or Player hand?
My 60 subscriber video!
Something I has wanting to finish for a while - making NPC work with minecarts - I really like Railcraft mod but it will be in 1.7.10 for some time it looks like so I made this in 1.8.
So now I can get to some questions I saw on the forum.
Good to see you are taking this up. I follow your wisdom closely on the NPCs thread.
Hey daottoad. Love your work. I've been following the npcs thread for a while and you've given me some useful advice.
I am currently working with 1.8.9. I have some complicated things I would like to do with scripting, but I am still very new and could use a little help with the simple stuff. For my first script, I would like to spawn a cloned npc into the world (presumably using spawnClone), by standing in a certain spot while a quest is active. What would be the simplest kind of script I could write to accomplish this? I've been educating myself on classes and modifiers, but I am still a little confused on how to write everything out properly using the customnpcs API.
Simple is very relative - I am still struggling with the new scripting format, so something that would be simple in 1.8 is not very straightforward for me - YET. But the best way to do this I think would be with a scripted block when you walk over it, then it will see if you have the quest and will spawn a NPC - think this would work for you?. I will work up and example and see what you think.
Thank you, I appreciate it, and that will certainly work!
In all honesty, I would like to make it so a certain sequence of places need to be visited during the quest before the script will work, but I think I could use command blocks to do this. The second-to-last place would spawn a block near the script block that it could test for, in addition to a player being nearby. I'll probably try to figure that script out on my own first, though (will post it if I succeed.)
It does seem that 1.8 scripting is very different. I haven't succeeded in converting any of my old ones yet. Normally to spawn an npc I would use /noppes clone spawn, but that command seems to have vanished for now =).
Here is what I got for you Endersloth on quest etc-- check it out .
And This video show how to spawn a NPC after death and after health changes.
I hadn't thought of using tempdata to reset scripts. That makes things much more streamlined. I appreciate you posting these scripts. Not only are they useful for what I had in mind, but they also provide a good example as to how the new API works. I will be trying more complex scripts as needed, and keeping up with this thread.
Need someone more creative/artistic/imaginative than me to do this in a BIG way.
Awesome vid! I'm assuming that was a quick skin change script with time parameters. I imagine it's a little time-consuming to do that even on a small scale.
Anyway, I'm back with what I thought was a simple script.
function init(event) {
event.npc.world.getTempdata().put("WepSwi",1);
}
function damaged(event) {
if (event.npc.world.getTempdata().put("WepSwi") == 1) {
event.npc.setLeftHand(getDisplayName("Iron Sword"));
event.npc.say("You’ll pay for that!");
event.npc.world.getTempdata().put("WepSwi",0);
}
}
function tick(event) {
if (event.npc.getHealth() == event.npc.getMaxHealth()) {
event.npc.setLeftHand(getDisplayName("Book"));
event.npc.world.getTempdata().put("WepSwi",1);
}
}
I am having trouble with definitions though. After troubleshooting it for a while, I couldn't manage to get past this error:
Wed Sep 07 11:46:32 PDT 2016 tab 1:
javax.script.ScriptException: TypeError: noppes.npcs.api.wrapper.NPCWrapper@3b71df6f has no such function "setLeftHand" in <eval> at line number 15
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:389)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)
at noppes.npcs.controllers.ScriptContainer.run(ScriptContainer.java:100)
at noppes.npcs.entity.data.DataScript.runScript(DataScript.java:62)
at noppes.npcs.EventHooks.onNPCTick(EventHooks.java:93)
at noppes.npcs.entity.EntityNPCInterface.func_70071_h_(EntityNPCInterface.java:258)
at noppes.npcs.entity.EntityCustomNpc.func_70071_h_(EntityCustomNpc.java:35)
at net.minecraft.world.World.func_72866_a(World.java:1860)
at net.minecraft.world.WorldServer.func_72866_a(WorldServer.java:699)
at net.minecraft.world.World.func_72870_g(World.java:1829)
at net.minecraft.world.World.func_72939_s(World.java:1661)
at net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:544)
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:701)
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:605)
at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:152)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:481)
at java.lang.Thread.run(Thread.java:745)
Caused by: <eval>:15 TypeError: noppes.npcs.api.wrapper.NPCWrapper@3b71df6f has no such function "setLeftHand"
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:106)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:71)
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154)
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253)
at jdk.nashorn.internal.scripts.Script$Recompilation$161$320A$\^eval\_.tick(<eval>:15)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:642)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:199)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383)
... 16 more
The script is supposed to have the npc draw a weapon in its right hand and make a threatening statement if attacked. It is supposed to sheath the weapon and reset the script once its health returns to full. It's meant to work if the npc has health regen, but no combat regen. There are probably other problems with the script too.
Ok first of all the setLeftHand requires a itemstack which is easily created by createItem().
second in your if statement you need to remember to "get" the tempdata.
and last you need a "inventory" after the npc and before setLeftHand - everything in the new api is very categorical
function init(event) {
event.npc.world.getTempdata().put("WepSwi",1);
}
function damaged(event) {
if (event.npc.world.getTempdata().get("WepSwi") == 1) {
event.npc.inventory.setLeftHand(event.npc.world.createItem("minecraft:iron_sword",0,1));
event.npc.say("You’ll pay for that!");
event.npc.world.getTempdata().put("WepSwi",0);
}
}
function tick(event) {
if (event.npc.getHealth() == event.npc.getMaxHealth()) {
event.npc.inventory.setLeftHand(event.npc.world.createItem("minecraft:book",0,1));
event.npc.world.getTempdata().put("WepSwi",1);
}
}
Hmm. That makes sense. I had originally put NPCInventory in that spot but it was of course undefined.
What is the difference between a method being under the itemstack interface (like getDisplayName) and simply having Itemstack as a modifier (like createItem)? I thought that all IItemstack methods would be under that interface, so I didn't initially look for createItem in IWorld.
I really don't know. I have had quite a lot of experience looking at the old api so I sometimes know where stuff can be.
I'm really hoping you intended on keeping this thread going as I have a question. I have added custom sounds to the customnpcs and they work fine when using the wand. The problem is I want to script the sounds in but I do not know how to call the sound file from the library. I assume that I need to use the executeCommand function and minecraft's playsound command but Minecraft disregards the sounds folder for custom sounds (the ones I add not the ones for mods) mostly because I am pointing the file path to the mod's folder like this: playsound customnpcs:mysound @p 24 68 -14 2 1. I know that is the wrong file path but I don't know where to point it otherwise and was hoping it would work. Is there a customnpc function that calls for playing a sound? I looked and couldn't find it. Thanks for any help you can give.
This works in 1.10 - the playsound command might have changed in other versions - sounds can be finicky in the sounds.json but if it works otherwise ???
Can find scripting info and ask questions on the "new" (relatively) discord channel https://discord.gg/2jZm88M
I'm using 1.7.10 for the other mods for this map so I am using the tabs. I did get it to work, thank you for the help!
npc.executeCommand("playsound customnpcs.gully_dwarf:gully_laughlow @a 57 65 -49 2 1"); this was the wrong code
npc.executeCommand("playsound customnpcs:gully_dwarf.gully_laughlow @a 57 65 -49 2 1"); this is right, I wasn't sure how to separate the folders in the command code
Do you know the difference in sound when you play it @a vs @p? Is it louder?
not sure you tell me - haven't tested it
Would it be possible to make a script that allows npcs to issue commands an a server as a player?