Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script] Multiple trap manager with flashing explosion example

1409902533

Edited 1409902761
Loki
Plus
As this is my first post I'm not quite sure of the markup yet to properly embed my script, however here is the link to the Gethub Gist. <a href="https://github.com/Loki386/Roll20-API/blob/master/traps.js" rel="nofollow">https://github.com/Loki386/Roll20-API/blob/master/traps.js</a> Any comments for improvement or how to markup my post would be welcomed =)
1409928759
The Aaron
Roll20 Production Team
API Scripter
Congrats on your first script! For markup, people usually put their scripts on gist.github.com, which the forum will display for you. It would be nice if it worked the same for gists on straight github.com. (feature request, I guess... ) I do have a few suggestions for you. =D On line 3, you're constructing a new trapManager, then conditionally using it on line 8. At a minimum, I'd move the construction inside if check. That way you only construct the object if you are going to use it, and not every time the GM moves a monster or changes it's hit points, etc.. Since the checkTrapTrigger() function isn't accessing any members of this, it doesn't actually need to be a new instance each time. I'd suggest setting up a single object that contains all of your functions and variables. If I were doing it, this is how I would reorganize your script: GIST: <a href="https://gist.github.com/shdwjk/054574d39c166d50865c" rel="nofollow">https://gist.github.com/shdwjk/054574d39c166d50865c</a>
1409928852
The Aaron
Roll20 Production Team
API Scripter
BTW, I also ran this through JS Lint and fixed some of it's less pedantic complaints. If you're looking to hone your JS craft, I recommend Javascript: The Good Parts by Douglas Crockford. Great book, fast and easy read.
1410195570

Edited 1410195885
Loki
Plus
Aaron, Thank you for your feedback. Is it that obvious this is my first js? ;) Your feedback was most informative and I see I have some studying up to do on proper js scoping syntax and best practices. The idea of wrapping a function within a shell function to control scoping is a new concept to me. Took a little research to understand the global singleton instantiation... var someClass = someClass || (function(){ //private objects\methods return { //public methods } })(); but I think I got it. Comming from the .net world I still would like to figure out how to define a "class interface" and enforce object types. I.E create a "trap" object which has properly scoped getter\setter properties and required methods such as the callback. Allowing you to inherit the base class and only have to define the callback event you want to happen when the trap is triggered. Next define a "trapManager" object which holds a collection of instantiated traps and on token movement checks to see if any of the traps were triggered and fire off its callback. Implementation in the manager would include a public method which is passed a type enforced instantiated trap object which will add the trap to the collection. Right now the only way I see to ensure a function parameter is really a "trap" object is to check if the expected objects are null and throw an exception. if(!trap || !trap.pageID || !trap.region || !trap.callback){throw someException}; I have my work cut out for me and as my coding time has been limited as of late I dont expect I'll update my script here past your previous suggestions. But none the less thank you for your time and feedback.
1410198258
The Aaron
Roll20 Production Team
API Scripter
No worries! Javascript class hierarchies are something I still struggle with. Mostly, I tend to ignore them I find. I have a strongly typed classical class background, so JS has been a bit tough to learn. What you probably want is to define an object that has the properties and functions you want, then use Object.create(&lt;base_object_instance&gt;) to created derived versions that you then change to be the traps you want. However, it might still be better to ignore the problem of having them derive from some base object, and make an object with all the default properties then use _.defaults(newobj,defobj) to fill them in: var defobj = { fired: false, page: Campaign().get('playerpageid'), xP1: 0, yP1: 0, xP2: 70, yP2: 70, fireEvent: function(){} }; // [...] var newTrap = _.defaults({fireEvent(){ log('fired!');}}, defobj); Something like that... Anyway, feel free to ping me if you want to chat about it!
1410205623
DXWarlock
Sheet Author
API Scripter
I still have NO idea what for example: var someClass = someClass || (function(){ is used for, or how to use it.. I look at Aarons scripts sometimes to get ideas for how to do something I'm doing in 50 lines easier...realize I don't understand 1/2 of it..and bull my way thru my script the old way I was anyway..haha
1410207952
The Aaron
Roll20 Production Team
API Scripter
=D The || (or) operator will return the first truthy thing in it's list. This is a distinction from other languages because it explicitly returns the value, not true or false. So var someClass = someClass || (function() { // [...] }() ); is equivalent to: var someClass = someClass; if( undefined === someClass) { someClass = (function() { // [...] }() ); } The first way is idiomatic Javascript for checking if something is already defined and then defining it if it isn't. It has probably grown out of the habit of defining new capabilities on existing objects if the browser isn't providing them. A good example is the Object.create() function, which is defined in ECMAScript 5, but not for previous implementations (We're lucking in that the API's engine is using an ECMAScript 5+ variant, so we don't have to worry about checking for it.) For older browsers, you can define Object.create simply like this: // create Object.create for old browsers Object.create = Object.create || function (o) { var F = function () {}; F.prototype = o; return new F(); }; undefined is falsey for old browsers, so the function is assigned, but for new ones, it just assigns the existing version back to itself. The right side of the || in the original question is an immediately invoked anonymous function: (function() { // do some stuff // return something }() ); The outer parenthesis are not required but are considered common curtesy, as they tell the reader (human) that what is coming up is the result of an invoked function, not the function itself (as in the Object.create example, where a function is what is being assigned). This technique is most used for creating object that have private members/methods. The scope of the function is only accessible to things created in the function, including those things that are returned from the function. So in this case: var foo = foo || (function() { var bar = 'qux'; return { doIt: function(s) { return bar+s+bar; } }; }() ); log(foo.doIt('-baz-')); // prints "qux-baz-qux" log(foo.bar); // prints undefined or '' or has an error (can't remember which) bar is only accessible to the doIt() function in the object returned from the anonymous function invocation. This is what's called a Closure. The anonymous function is said to close over the state when it's executed. Hope that clears it up? If not, feel free to ask, I'm happy to chat at length about things. =D