Page 1 of 1
Help with a script
Posted: Tue Aug 21, 2012 1:33 pm
by Blue Dragon
Hello Xuri,
With a little time here, and a little more knowledgeable of this method of script, here I was trying to customize and make more attractive the script Ettin throw stones...
Well, I made this script bellow, still not quite ready, but due to my lack of knowledge, tests is stopped because "myPlayer is not defined / line 54 is null...". I tried several ways are my little knowledge to make it work, but I could not this.
If you're not too busy and can help, follows the order:
1-In function OnTimer says myPlayer is not defined. How fix this error in the current script (write what?), and how to fix it when appear some these phrases?
2-I do not still understand very good the utility of terms "return true" and "return false"; After all, what are its uses and when should I put them?
That is, if you're not too busy and can resolve these questions for me, I thank.
var EfeitoMovimentoRochaID1 = 0x1363;
var EfeitoMovimentoRochaID2 = 0x1362;
var AcertoRochaSom = 0x145;
var GritoHomemSom = 0x540;
var GritoMulherSom = 0x14e;
function onCombatStart( myNPC, myPlayer )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 7 )
{
var dice;
dice = RollDice( 1,3,0 );
if( dice == 1 )
{
myNPC.TurnToward( myPlayer );
myNPC.frozen = 0;
myNPC.StartTimer( 500, 0, true );
}
if (dice == 2)
{
myNPC.TurnToward( myPlayer );
myNPC.frozen = 0;
myNPC.StartTimer( 500, 1, true );
}
}
}
function onTimer( myNPC, timerID )
{
if( timerID == 0 )
{
myNPC.DoAction ( 11 );
myNPC.EmoteMessage( "*"+myNPC.name+" pega uma rocha no chao*" );
myNPC.StartTimer( 2000, 2, true );
}
if( timerID == 1 )
{
myNPC.DoAction ( 11 );
myNPC.EmoteMessage( "*"+myNPC.name+" pega uma gigantesca rocha no chao*" );
myNPC.StartTimer( 2000, 3, true );
}
if( timerID == 2 )
{
DoMovingEffect( myNPC, myPlayer, EfeitoMovimentoRochaID1, 0x10, 0x00, false );
myNPC.frozen = 0;
myPlayer.SoundEffect( AcertoRochaSom, true );
if( myPlayer.gender == 0 )
{
myPlayer.SoundEffect( GritoHomemSom, true );
}
else if( myPlayer.gender == 0 )
{
myPlayer.SoundEffect( GritoMulherSom, true );
}
if( myPlayer.isonhorse )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 5 )
{
myPlayer.Dismount();
myPlayer.EmoteMessage( "*Voce foi atingido em cheio por uma rocha!!*", false );
myPlayer.health = ( myPlayer.health -15 );
myPlayer.stamina = ( pDefender.myPlayer -1 );
}
else
{
myPlayer.EmoteMessage( "*Voce foi atingido de raspao por uma rocha!*", false );
myPlayer.health = ( myPlayer.health -10 );
myPlayer.stamina = ( myPlayer.stamina -1 );
}
}
else
{
if( iNum > 5 )
{
myPlayer.EmoteMessage( "*Voce foi atingido em cheio por uma rocha!!*", false );
myPlayer.health = ( myPlayer.health -15 );
myPlayer.stamina = ( pDefender.myPlayer -1 );
}
else
{
myPlayer.EmoteMessage( "*Voce foi atingido de raspao por uma rocha!*", false );
myPlayer.health = ( myPlayer.health -10 );
myPlayer.stamina = ( myPlayer.stamina -1 );
}
}
}
if( timerID == 3 )
{
DoMovingEffect( myNPC, myPlayer, EfeitoMovimentoRochaID2, 0x10, 0x00, false );
myNPC.frozen = 0;
myPlayer.SoundEffect( AcertoRochaSom, true );
if( myPlayer.gender == 0 )
{
myPlayer.SoundEffect( GritoHomemSom, true );
}
else if( myPlayer.gender == 0 )
{
myPlayer.SoundEffect( GritoMulherSom, true );
}
if( myPlayer.isonhorse )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 5 )
{
myPlayer.Dismount();
myPlayer.EmoteMessage( "*Voce foi atingido em cheio por uma gigantesca rocha!!*", false );
myPlayer.health = ( myPlayer.health -20 );
myPlayer.stamina = ( pDefender.myPlayer -1 );
}
else
{
myPlayer.EmoteMessage( "*Voce foi atingido de raspao por uma gigantesca rocha!*", false );
myPlayer.health = ( myPlayer.health -15 );
myPlayer.stamina = ( myPlayer.stamina -1 );
}
}
else
{
if( iNum > 5 )
{
myPlayer.EmoteMessage( "*Voce foi atingido em cheio por uma gigantesca rocha!!*", false );
myPlayer.health = ( myPlayer.health -20 );
myPlayer.stamina = ( pDefender.myPlayer -1 );
}
else
{
myPlayer.EmoteMessage( "*Voce foi atingido de raspao por uma gigantesca rocha!!*", false );
myPlayer.health = ( myPlayer.health -15 );
myPlayer.stamina = ( myPlayer.stamina -1 );
}
}
}
}
Re: Help with a script
Posted: Sun Aug 26, 2012 7:49 pm
by Xuri
The problem is that "myPlayer" only exists within the scope of the onCombatStart-function. Once the script goes to a different function (like OnTimer), the reference to that variable is lost.
To work around that, you can store the variable reference somewhere else - like storing the character-serial in a custom-tag in one function, then retrieving it again in the next function. Here is one way you could do that:
function onCombatStart( myNPC, myPlayer )
{
...
if (dice == 2)
{
myNPC.TurnToward( myPlayer );
myNPC.frozen = 0;
myNPC.SetTag( "targetserial", ( myPlayer.serial & 0x00FFFFFF ) );
myNPC.StartTimer( 500, 1, true );
}
}
}
function onTimer( myNPC, timerID )
{
var TargetSerial = myNPC.GetTag( "targetserial" );
var TargetChar = CalcCharFromSer( TargetSerial );
...
}
(TargetChar in the second function would in this case be the same character as myPlayer in the first function.)
As for your second question,
return true/false usage depends on the event (onCombatStart, onUse, etc). Ideally the result of a true/false return should be documented per event in the
UOX3 JS Documentation. If it's missing for some, let me know which and I will try to fix that.
Re: Help with a script
Posted: Mon Aug 27, 2012 5:29 am
by Blue Dragon
Very good Xuri , thank you! Now the target worked perfectly!
But, unfortunately, some things still did not work. And here comes I ask you again. If you can respond.
1-Why, excerpts below do not work?
TargetChar.Dismount ();
TargetChar.SysMessage ( "You were hit on the head by a rock." );
TargetChar.health = ( TargetChar.health -20 );
TargetChar.stamina = ( TargetChar.stamina -1);
If the target is me or another NPC, takes not damage in your life and stamina. If I'm a target of myNPC, I not receive "SysMessage" and also not suffer "Dismount". I do not know what are the reasons ...
2-If I want the damage is, for example, a random number from 10 to 20, to exit the routine of single value, what should I put in there in front of the "TargetChar.health."
3-I'm creating a gump script and some features of blacksmithing. It's getting huge script. In making a function to restore weapons used, I got the same problem cited above. In using of "MyTarget" in "OnTimer" function, the script does not work. I tried the same way here of the Ettin script, catching the serial item, but it did not work.
How would I do that for the hp weapon, the targeted in function "onCallback0", is recovered in the function "OnTimer".? Would be a way different from the one shown in the script Ettin?
Current script with corrections made.
var EfeitoMovimentoRochaID1 = 0x1363;
var EfeitoMovimentoRochaID2 = 0x1362;
var AcertoRochaSom = 0x145;
var GritoHomemSom = 0x540;
var GritoMulherSom = 0x14e;
function onCombatStart( myNPC, myPlayer )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 8 )
{
var dice;
dice = RollDice( 1,2,0 );
if( dice == 1 )
{
myNPC.TurnToward( myPlayer );
myNPC.frozen = 1;
myNPC.SetTag( "targetserial", ( myPlayer.serial & 0x00FFFFFF ) );
myNPC.StartTimer( 1000, 0, true );
}
else if (dice == 2)
{
myNPC.TurnToward( myPlayer );
myNPC.frozen = 1;
myNPC.SetTag( "targetserial", ( myPlayer.serial & 0x00FFFFFF ) );
myNPC.StartTimer( 1000, 1, true );
}
}
}
function onTimer( myNPC, timerID )
{
var TargetSerial = myNPC.GetTag( "targetserial" );
var TargetChar = CalcCharFromSer( TargetSerial );
if( timerID == 0 )
{
myNPC.DoAction ( 11 );
myNPC.EmoteMessage( "*"+myNPC.name+" pega uma rocha no chao*" );
myNPC.StartTimer( 2000, 2, true );
}
if( timerID == 1 )
{
myNPC.DoAction ( 11 );
myNPC.EmoteMessage( "*"+myNPC.name+" pega uma gigantesca rocha no chao*" );
myNPC.StartTimer( 2000, 3, true );
}
if( timerID == 2 )
{
DoMovingEffect( myNPC, TargetChar, EfeitoMovimentoRochaID1, 0x10, 0x00, false );
TargetChar.SoundEffect( AcertoRochaSom, true );
myNPC.frozen = 0;
if( TargetChar.gender == 0 )
{
TargetChar.SoundEffect( GritoHomemSom, true );
}
else if( TargetChar.gender == 1 )
{
TargetChar.SoundEffect( GritoMulherSom, true );
if( TargetChar.isonhorse )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 6 )
{
TargetChar.Dismount();
TargetChar.SysMessage( "Voce foi atingido em cheio por uma rocha." );
TargetChar.health = ( TargetChar.health -20 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
else
{
TargetChar.SysMessage( "Voce foi atingido de raspao por uma rocha." );
TargetChar.health = ( TargetChar.health -10 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
}
else
{
if( iNum > 5 )
{
TargetChar.SysMessage( "Voce foi atingido em cheio por uma rocha." );
TargetChar.health = ( TargetChar.health -20 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
else
{
TargetChar.SysMessage( "Voce foi atingido de raspao por uma rocha." );
TargetChar.health = ( TargetChar.health -10 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
}
}
else
{
return true;
}
}
if( timerID == 3 )
{
DoMovingEffect( myNPC, TargetChar, EfeitoMovimentoRochaID2, 0x10, 0x00, false );
TargetChar.SoundEffect( AcertoRochaSom, true );
myNPC.frozen = 0;
if( TargetChar.gender == 0 )
{
TargetChar.SoundEffect( GritoHomemSom, true );
}
else if( TargetChar.gender == 1 )
{
TargetChar.SoundEffect( GritoMulherSom, true );
if( TargetChar.isonhorse )
{
var iNum = RandomNumber( 0, 10 );
if( iNum > 6 )
{
TargetChar.Dismount();
TargetChar.SysMessage( "Voce foi atingido em cheio por uma gigantesca rocha." );
TargetChar.health = ( TargetChar.health -30 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
else
{
TargetChar.SysMessage( "*Voce foi atingido de raspao por uma gigantesca rocha!*" );
TargetChar.health = ( TargetChar.health -15 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
}
else
{
if( iNum > 5 )
{
TargetChar.SysMessage( "*Voce foi atingido em cheio por uma gigantesca rocha!!*" );
TargetChar.health = ( TargetChar.health -30 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
else
{
TargetChar.SysMessage( "*Voce foi atingido de raspao por uma gigantesca rocha!!*" );
TargetChar.health = ( TargetChar.health -15 );
TargetChar.stamina = ( TargetChar.stamina -1 );
}
}
}
else
{
return true;
}
}
Re: Help with a script
Posted: Mon Oct 22, 2012 3:37 pm
by Xuri
Sorry for the extreme delay on this reply. Not sure if you still need this, but I'll try to answer it anyways.
1) My best guess on this is that it's not playing on your character/NPCs because of your gender. Currently, for both timerID 2 and timerID 3, your script seems to play a soundeffect only for anyone with gender 0, while the dismount/damage/sysmessage bits only runs for gender 1.
2)
var rndDamage = RandomNumber( 10, 20 );
TargetChar.health = ( TargetChar.health - rndDamage );
Alternatively:
var rndDamage = RandomNumber( 10, 20 );
TargetChar.Damage( rndDamage );
3) Not sure about this one until I see the script.
Re: Help with a script
Posted: Tue Oct 23, 2012 4:07 pm
by Blue Dragon
Do not worry about the delay. You're pretty busy and I've been very busy also.
I still had not found the problem which occurred in this script, and once again you nailed it in your reply! As I did not know which was a script when I started interacting with UOX3, am learning to few, and therefore I not noticed a flaw as simple as that. For me everything was normal, hehehe...
Now it's normal! Players disassemble and take random damage, as you explained how to do it well. But do not know why, NPC's do not take damage... This question also remains about the Cannon script of Dragon Slayer... Theoretically, to my knowledge it is all right, but NPCs do not take damage in your life, only the players...
On question number 3, I will post my "crazy script" and if you know the answer or want to make any comment, feel free. Technically I can say he was my first script that I made myself, just watching other scripts, reading guides, among others....
Link the topic of the script blacksmith:
viewtopic.php?f=3&t=2424&p=12629#p12629
Thanks for the reply Xuri.
Re: Help with a script
Posted: Tue Oct 23, 2012 6:14 pm
by Xuri
Ah. Storing and fetching serials for items is slightly different than for characters, which is why it worked for you in the ettin-script (you store a character there).
Here's how to do the same for an item:
Storing the serial: (in onCallback0)
pUser.SetTag( "targser1", myTarget.GetSerial(1) );
pUser.SetTag( "targser2", myTarget.GetSerial(2) );
pUser.SetTag( "targser3", myTarget.GetSerial(3) );
pUser.SetTag( "targser4", myTarget.GetSerial(4) );
Fetching the serial: (in onTimer)
var myTarget = CalcItemFromSer( pUser.GetTag( "targser1"), pUser.GetTag( "targser2"), pUser.GetTag( "targser3"), pUser.GetTag( "targser4"));
Re: Help with a script
Posted: Tue Oct 23, 2012 8:12 pm
by Blue Dragon
So is this, I was doing as in ettins. But you put four examples, I need to put four or is just for me to see how it works in the case of more than one item?
I laid there like you said, but appeared "MyTarget has no properties".
I have to do something more than what you posted? I put everything in the right places...
It would be basically for iUsed (blacksmmith hammer) and myTarget (weapon you choose) lost and regenerate their durability respectively, in ontimer 2.
Re: Help with a script
Posted: Tue Oct 23, 2012 8:21 pm
by Xuri
Oops! I was referencing myTarget when doing GetTag, instead of pUser! Fixed that now. Sorry.
The reason why there are four lines in my example is that each line is only grabbing 1/4th of the full item serial. So all four lines (and four tags) are necessary for any one item. You can then fetch the item object based on those four serials later on, in the timer function.
Re: Help with a script
Posted: Tue Oct 23, 2012 8:57 pm
by Blue Dragon
Thanks Xuri. For the item to be restored, everything went right. But how do the hammer lose durability by repair the item?
I laid bellow and it seems like the durability of the hammer ends up being the same as the item repaired...
function onUseChecked ( pUser, iUsed )
{
pUser.SetTag( "targser5", iUsed.GetSerial(1) );
pUser.SetTag( "targser6", iUsed.GetSerial(2) );
pUser.SetTag( "targser7", iUsed.GetSerial(3) );
pUser.SetTag( "targser8", iUsed.GetSerial(4) );
...
}
if( timerID == 2 )
{
var iUsed = CalcItemFromSer( pUser.GetTag( "targser5"), pUser.GetTag( "targser6"), pUser.GetTag( "targser7"), pUser.GetTag( "targser8"));
iUsed.health = ( myTarget.maxhp -2 );
iUsed.maxhp = ( myTarget.maxhp -2 );
...
}
And I noticed that the durability of the tooltip does not change at the moment, it's only refresh when I moved the item repaired in the backpack. Is this normal?
Re: Help with a script
Posted: Tue Oct 23, 2012 10:05 pm
by Xuri
If you want to be able to modify both the hammer (iUsed) and the targeted item in the timer-function, you need to store their serials as separate tags on the character, and retrieve them into separate variables in the onTimer function.
To force-refresh the item you modified, you could try doing something like this after modifying it:
iUsed.PlaceInPack();
...this should in theory try to place the object at a random location inside the container it's currently in, and might update the tooltip at the same time.
Oh, and I just remembered an alternative to the "store serial in custom tags, retrieve serial later"-method.
To temporarily store an object variable on a (player only) character:
socket.tempObj = iUsed;
or
pUser.socket.tempObj = iUsed; (If you don't have a direct reference to the socket)
To retrieve the stored object:
var myObj = socket.tempObj;
or
var myObj = pUser.socket.tempObj; (If you don't have a direct reference to the socket)
This can behave more randomly than the custom tags though, as the tempObj variable can in theory be overwritten by other events happening in the game, so there's no guarantee that you retrieve the same object that you put in, unless it's a _very_ short time between storing and retrieving it.
Re: Help with a script
Posted: Tue Oct 23, 2012 11:11 pm
by Blue Dragon
The durability of the hammer was getting like the item to be restored, due the following reason below... How much distraction on my part!! ¬ ¬
iUsed.health = (myTarget.maxhp -2);
iUsed.maxhp = (myTarget.maxhp -2);
Should be...
iUsed.health = (iUsed.maxhp -2);
iUsed.maxhp = (iUsed.maxhp -2);
About updating of the tooltip, with this hint you gave, it worked! Although the hammer is used only when equipped, put "iUsed.PlaceInPack ();" and he updated the tooltip, but it was not moved to backpack. But this is not a problem! And as you said, it would be moved to the "backpack" where it was, but as it was equipped in character, was just updated.
Now the damaged weapon was restored and moved to the center of the backpack, which also updated the your tooltip. A simple and unimportant observation is that apparently the object is not moved to a random location of the backpack, but always to the center of the backpack.
But that's it. Thanks again for your time and patience, Xuri. Now everything is working perfectly! But forward I will improve the whole script and will post full here.