Register FAQ Search Today's Posts Mark Forums Read
Go Back   JazzJackrabbit Community Forums » Open Forums » JCS & Scripting

AngelScript Requests & Help

Reply
 
Thread Tools
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 10, 2014, 11:11 AM
Violet CLM is offline
Reply With Quote
jjDrawSprite, for better or worse, doesn't take the initiative to load sprites from anims.j2a if they haven't already been loaded for that level. To remedy this, either place a corresponding object or ambient sound event somewhere in JCS, or else call jjOBJ::determineCurAnim, which does try to load missing sprites.

(Please hold any concerns about that a) not making sense or b) not being documented, because you're right. There wasn't time/understanding to put in place a more elaborate/appropriate API for such things, but there needed to be some way of loading sprites in the meantime, so determineCurAnim got to be an interim solution)
__________________
DennisKainz

JCF Member

Joined: Dec 2005

Posts: 422

DennisKainz is notorious for his worthless posts

Jan 10, 2014, 12:04 PM
DennisKainz is offline
Reply With Quote
You have been very helpful! Thank you!
_______

I don't know how to use all the algebra operations. I only know how to use the % in something like "obj.xPos%32" to module the value in a range of 32.

Where can I find the whole list of algebra operations in scripting?

And how do I repeat an event many times in a game tick? For example, I would like to spawn 64 particles of pixel type on Jazz to simulate bleeding, but I can only add 1 particle per tick.

Last edited by DennisKainz; Jan 10, 2014 at 02:52 PM.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 10, 2014, 03:42 PM
Violet CLM is offline
Reply With Quote
At this point you're just asking about how the scripting language works, so I'd suggest reading the docs, particularly the first three sections. Or at least skim and look for words like "operator" and "loop."
__________________
DennisKainz

JCF Member

Joined: Dec 2005

Posts: 422

DennisKainz is notorious for his worthless posts

Jan 10, 2014, 11:17 PM
DennisKainz is offline
Reply With Quote
That is exactly the advice I needed. Thank you again.

There's one thing I can't find in the manual, though. How do I remove the decimal parts from a number?

For example, I want to check the enemy's x speed, but instead of checking it as "1.25" or "4.0625" or "3.785" I want it to be checked respectively as "1", "4" or "3".

Shortly, to check the numbers as natural, non decimal numbers.

And there's a new problem: I can't set a walking enemy's x speed to its current value minus something. I ask the game to calculate "necro.xSpeed = necro.xSpeed - 0.0625", but it converts it into "necro.xSpeed = necro.xSpeed" when I do, automatically discarding the subtraction part.

And I think it also converts xSpeed from "0" to "1" automatically when a walking enemy is on walking state.

And I can't find a behavior that respects everything. The pickup behavior respects the x and y speed, but always blocks on collision. The spark one doesn't block on collision and respects x and y speed, but ignores you in a range outside 240 or something, which isn't ok if you play in 640x480. Can the AngelScript experts create a behavior which respects everything you input to it, and you decide whether it respects collisions or not?

Also, when I kill an object and play a sound to it, the sound stops along with the object's death, and I don't want to add expressions apart to make the sound continue.

I'm sorry about bothering you so much. I swear I try to figure stuff out myself, but my logic skills aren't as high as yours.

Last edited by DennisKainz; Jan 13, 2014 at 06:38 AM.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 18, 2014, 11:46 AM
Violet CLM is offline
Reply With Quote
Editing your post didn't bump the thread, so it took me a while to see this:
Quote:
Originally Posted by DennisKainz View Post
There's one thing I can't find in the manual, though. How do I remove the decimal parts from a number?
I don't remember which syntax AS uses, but either int(number) or (int)(number) should work.
Quote:
I ask the game to calculate "necro.xSpeed = necro.xSpeed - 0.0625", but it converts it into "necro.xSpeed = necro.xSpeed" when I do, automatically discarding the subtraction part.

And I think it also converts xSpeed from "0" to "1" automatically when a walking enemy is on walking state.
0.0625 should be large enough to register as a difference between float values. More likely this is a quirk of BEHAVIOR::WALKINGENEMY. It's built for walking back and forth at a constant speed, and the more you want that to change, the less likely it gets that it'll do everything you need.
Quote:
Also, when I kill an object and play a sound to it, the sound stops along with the object's death, and I don't want to add expressions apart to make the sound continue.
Post the code? I'm not sure what this would be.



In the "Requests" department: lwe9.j2l.
__________________
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Feb 15, 2014, 04:15 PM
Love & Thunder is offline
Reply With Quote
Hey, so this is probably going to make me seem like an idiot, but how do I check whether or not a player has destroyed a tile of destructible scenery? (If it's of any help, I want it to activate a trigger scenery event as a result, and all of this is supposed to be in singleplayer mode)
__________________
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Feb 15, 2014, 04:18 PM
Violet CLM is offline
Reply With Quote
jjTileGet would probably be simplest.
__________________
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Feb 15, 2014, 04:46 PM
Love & Thunder is offline
Reply With Quote
Okay, it's good to know that I'm doing that part right, but it also means that I've almost definitely got the syntax wrong...
Code:
void onMain {
    if jjTileGet(4,11,29) == 10 {
        jjSwitchTrigger(1)
    }
}
(If it wasn't already obvious, I'm a complete Angelscript/C/C++ noob)
__________________
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Feb 15, 2014, 07:31 PM
Violet CLM is offline
Reply With Quote
This isn't Python, so you'll need to wrap some parentheses around the condition. if (jjTileGet(4,11,29) == 10) {.
__________________
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Feb 15, 2014, 08:21 PM
Love & Thunder is offline
Reply With Quote
I did try that at one point(And I just double-checked now) -- still not working.
__________________
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Feb 15, 2014, 09:45 PM
Violet CLM is offline
Reply With Quote
Oh, right... you also need () after onMain.

Remember to turn on AngelscriptDebug in plus.ini if you're writing code. It gives you line numbers and things for syntax errors.
__________________
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Feb 16, 2014, 06:46 AM
Love & Thunder is offline
Reply With Quote
Thanks, it works... Sort of.
New problem: If I have the destruct scenery change the tile into an animated tile(Using WebJCS), the script doesn't work(Although, if I use a non-animated tile, it works perfectly).
Here's what the code looks like now:
Code:
void onMain() {
    if ((jjTileGet(4,10,28) == 0) && (jjTriggers[1] == false) == true) {
        jjSwitchTrigger(1);
    }
}
(The extra part I put that checks if the trigger is on prevents it from toggling the trigger every gametick)
__________________
cooba

JCF Veteran

Joined: Jan 2004

Posts: 7,814

cooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of light

Feb 16, 2014, 07:43 AM
cooba is offline
Reply With Quote
Code:
(jjTriggers[1] == false) == true
What.
Code:
void onMain() {
	if (jjTileGet(4, 10, 28) == 0 && !jjTriggers[1]) {
		jjTriggers[1] = true;
	}
}
Also, jjTileGet can check for animated tiles very simply (there's an entire appendix dedicated to that, pretty much).
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Feb 16, 2014, 09:03 AM
Love & Thunder is offline
Reply With Quote
Quote:
Originally Posted by cooba View Post
What.
It checks two things, and if both of them return true, then it triggers.
Quote:
Originally Posted by cooba View Post
Also, jjTileGet can check for animated tiles very simply (there's an entire appendix dedicated to that, pretty much).
Ah, my mistake was that I didn't put the "+ TILE::ANIMATED" flag on, although the real problem was me misinterpreting part of the AS Readme.
Now that I think about it, it was a really stupid mistake(Although, that's generally how I learn these things).
Anyway, thanks for the help.
__________________
KRSplatinum

JCF Member

Joined: Jul 2013

Posts: 263

KRSplatinum is a forum legendKRSplatinum is a forum legend

Mar 7, 2014, 10:35 PM
KRSplatinum is offline
Reply With Quote
Code to morph Spaz to Jazz by Nick of epictest.j2l

Quote:
Code:
// The goal of this is to morph to Jazz for a test level

void onFunction1() {
	p.morphTo(CHAR::JAZZ);
}

// Assume Jazz has greater than 0 health upon spawning

void onFunction2() {
        p.health= 0;
        switch(jjRandom() % 3) {
		case 0: jjChat("/me |||Burned in Fire"); break;
		case 1: jjChat("/me |||Burned in Fire"); break;
		case 2: jjChat("/me |||Burned in Fire"); break;
	}
}






// Access the code to automatically recognize Spaz's popularity



void onFunction3() {
        p.morphTo(CHAR::SPAZ);
}
A.I.T.

JCF Member

Joined: Feb 2014

Posts: 2

A.I.T. is doing well so far

Mar 11, 2014, 07:19 AM
A.I.T. is offline
Reply With Quote
Is there any way of giving objects shields(namely enemies so that they can shoot with them and pickups so that they hurt the player upon contact until shieldTime runs out)?

I have disabled the functions of the fire shield so far:


void onLevelLoad() {
jjObjectPresets[OBJECT::FIRESHIELD].behavior = Incendie;
}

void Incendie(jjOBJ@ boule) {
boule.behave(BEHAVIOR::MONITOR, false);
if (boule.state == STATE::KILL) boule.state = STATE::ACTION;
}
void onPlayer(jjPLAYER@ play) {
if (play.shieldType == 1) play.shieldTime = 0;
}

Pointing out the position of the specific object afterwards does not seem to work. Besides, I have gone through about 80 animations in the ''Pickups'' section and still have not found one of an active shield. I suppose the parameters shieldType and shieldTime should also somehow be added to the jjOBJ class(?).

Thank you in advance!
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Mar 11, 2014, 01:18 PM
Violet CLM is offline
Reply With Quote
Nope.
__________________
Stavros

JCF Member

Joined: Mar 2014

Posts: 1

Stavros is doing well so far

Mar 12, 2014, 10:08 AM
Stavros is offline
Reply With Quote
When I start my level in multiplayer mode, the result of following code is always 20, but in single player there are random values.. do you know what's the reason behind that??

Code:
void onLevelLoad()
{
	for(int i = 0; i <= 20; i++)	jjAddObject(OBJECT::APPLE, jjRandom()%3000, jjRandom()%3000);
}
int count()
{
	int x = 0;
	for (int i = 1; i < jjObjectCount-1; i++) if(jjObjects[i].isActive) x++;
	return x;
}
void onMain()
{
	if(jjGameTicks%210 == 0) jjAlert(""+count());
}
@Sir Ementaler: Thanks!

Last edited by Stavros; Mar 12, 2014 at 11:34 AM.
Seren

JCF Member

Joined: Feb 2010

Posts: 868

Seren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to all

Mar 12, 2014, 10:26 AM
Seren is offline
Reply With Quote
Single player mode saves memory and improves performance by deactivating most objects when they are too far away from the player. See jjOBJ::deactivates.

Additionally you probably do not want to use jjObjectCount-1 in your code because that means the object will not be registered if it's the final object.
__________________

I am an official JJ2+ programmer and this has been an official JJ2+ statement.
incandescentembers

JCF Member

Joined: Oct 2012

Posts: 62

incandescentembers is doing well so far

Mar 15, 2014, 01:37 AM
incandescentembers is offline
Reply With Quote
Let me create a post with bunch of large questions regarding the possibilities of Angel Script (some of them I've already asked in SWAG thread, but I don't want to make more offtopings). I'm sorry if some of that was already explained, I just want to put all my ambiguities together. I will really appreciate if someone will take his time and patience and will give me exhaustive answers for all of these points:
  1. Can you modify the JCS with the AngelScript? For example: can you add more layers (that would be super useful for people who love making BIG tilesets, so they wouldn't have to worry about including same tiles for million times just with different backgrounds)

  2. Is there any way to somehow incorporate enemies' behaviors from JJ1? For example I love that mechanic snake from Orbitus in JJ1 and I would love to see that creature in JJ2. His movements seem to be very simple. The graphics for all JJ1 enemies are availible freely on the web. It looks to me like an easy job for someone who knows coding. Am I wrong?

  3. How enemies work in JJ2 anyways? I know that there are some enemies that don't work properly, and there are some dublets just with different graphics (like Lizard and Lizard Xmas, etc.). Is there a way to add more custom enemies (and by this I mean like real ENEMIES or BOSSES that are easy to place in JCS for noobs like me who don't know any fancy coding, not some inventions like flying Pharao-rabbit from Ozymandius) to JJ2 (doing some coding, hacking or something like that) or the limitations don't allow that? If not, it is still possible to just replace the existing ones, right? By modifying their behaviors and graphics?

  4. Is there anyway to transfer some objects from JJ1 to JJ2? I think the most interested thing was the shield, the idea of diamonds floating around the rabbit, and losing each one after getting hit.

    Also I think in my head that theoretically it is possible to add the large +15 gun circles from JJ1. With the sprite editor you could modify the graphics of the JJ2 gun screens, and then somehow modify the sound. Does this sounds right?

  5. Is there any way to set up that after killing a boss you won't finish the level and can go on playing the same level the boss was in?

  6. Is there any way to set up that after warping the coin-warp the coins won't change into diamonds?

  7. Is there any way to set up bonus levels? For example by collecting certain ammount of diamonds (what are they for anyways in JJ2? I always thought that for some kind of bonus stages, since they are even counted at the end of each level!).

  8. Is there any way to set up the secret level system to work correctly?

  9. Is there any way to elminate sugar rushes, especially that annoying music, which destroys the atmosphere of the level by stopping it's music and jumping with that not-fitting 20 seconds of madness?

  10. Is there any way to change the ammo limit to 999, just like in Jazz 1? 99 seems veeeeeery little...
Seren

JCF Member

Joined: Feb 2010

Posts: 868

Seren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to all

Mar 15, 2014, 03:16 AM
Seren is offline
Reply With Quote
Quote:
Originally Posted by incandescentembers View Post
Can you modify the JCS with the AngelScript? For example: can you add more layers (that would be super useful for people who love making BIG tilesets, so they wouldn't have to worry about including same tiles for million times just with different backgrounds)
AngelScript doesn't modify anything but level gameplay. JCS, J2L and JJ2 don't support more than 8 layers. A visual illusion of more layers can be created with use of AngelScript functions jjCANVAS::drawTile and jjDrawTile but there may be slowdowns associated with this approach.
Quote:
Originally Posted by incandescentembers
Is there any way to somehow incorporate enemies' behaviors from JJ1? For example I love that mechanic snake from Orbitus in JJ1 and I would love to see that creature in JJ2. His movements seem to be very simple. The graphics for all JJ1 enemies are availible freely on the web. It looks to me like an easy job for someone who knows coding. Am I wrong?
I didn't play JJ1 but I can easily answer you can script nearly any enemy behavior you want and you cannot add any graphics at all unless you include them in the tileset. If they're present in the tileset, you can probably replicate any behavior as long as it doesn't involve external sounds as well, which there is no way to add.
Quote:
Originally Posted by incandescentembers
How enemies work in JJ2 anyways? I know that there are some enemies that don't work properly, and there are some dublets just with different graphics (like Lizard and Lizard Xmas, etc.). Is there a way to add more custom enemies (and by this I mean like real ENEMIES or BOSSES that are easy to place in JCS for noobs like me who don't know any fancy coding, not some inventions like flying Pharao-rabbit from Ozymandius) to JJ2 (doing some coding, hacking or something like that) or the limitations don't allow that? If not, it is still possible to just replace the existing ones, right? By modifying their behaviors and graphics?
If butterflies count. This question looks unclear to me because you appear to be specifically asking for modifying JJ2 and not anything related to scripting, and this is essentially a scripting thread. If this answers your question, JCS and JJ2 are limited to 256 events and the amount of behaviors is limited by a number so huge you can call it unlimited. Hacking JJ2 with a new project would be many times more difficult than scripting new enemies. JJ2+ won't add enemies on request because the amount of events is too limited and scripting is provided.
Quote:
Originally Posted by incandescentembers
Is there anyway to transfer some objects from JJ1 to JJ2? I think the most interested thing was the shield, the idea of diamonds floating around the rabbit, and losing each one after getting hit.

Also I think in my head that theoretically it is possible to add the large +15 gun circles from JJ1. With the sprite editor you could modify the graphics of the JJ2 gun screens, and then somehow modify the sound. Does this sounds right?
This was answered in the previous questions because objects and enemies are internally the same thing.
Quote:
Originally Posted by incandescentembers
Is there any way to set up that after killing a boss you won't finish the level and can go on playing the same level the boss was in?
Yes but there is no direct setting for that so it's hard to tell how difficult that is to do.
Quote:
Originally Posted by incandescentembers
Is there any way to set up that after warping the coin-warp the coins won't change into diamonds?
This was directly answered in the readme in the Global Properties section. Please read the manual before asking questions on forums.
Quote:
Originally Posted by incandescentembers
Is there any way to set up bonus levels? For example by collecting certain ammount of diamonds (what are they for anyways in JJ2? I always thought that for some kind of bonus stages, since they are even counted at the end of each level!).
Yes as long as you aren't specifically asking for 3D bonus stages like those JJ1 has. JJ2 doesn't use gems for anything but points. It was supposed to give you an extra life for every 100 gems but from what I recall they couldn't get the code to work correctly and it was commented out.
Quote:
Originally Posted by incandescentembers
Is there any way to set up the secret level system to work correctly?
It already does.
Quote:
Originally Posted by incandescentembers
Is there any way to elminate sugar rushes, especially that annoying music, which destroys the atmosphere of the level by stopping it's music and jumping with that not-fitting 20 seconds of madness?
Yes, it was done in No Way Out.
Quote:
Originally Posted by incandescentembers
Is there any way to change the ammo limit to 999, just like in Jazz 1? 99 seems veeeeeery little...
This was directly answered in the readme in the jjWEAPON section.
__________________

I am an official JJ2+ programmer and this has been an official JJ2+ statement.
incandescentembers

JCF Member

Joined: Oct 2012

Posts: 62

incandescentembers is doing well so far

Mar 16, 2014, 09:42 AM
incandescentembers is offline
Reply With Quote
Quote:
Originally Posted by Sir Ementaler View Post
I didn't play JJ1 but I can easily answer you can script nearly any enemy behavior you want and you cannot add any graphics at all unless you include them in the tileset. If they're present in the tileset, you can probably replicate any behavior as long as it doesn't involve external sounds as well, which there is no way to add.
Can it be animated? Let's say I will put all the tiles needed for animation of some enemy - will this work?

I know I may be asking for too much, but can any one show me how can I build the easiest enemy that comes to my mind: that spiky ball from Technoir, which just moves from one wall to another. Let's just say that I have a one tile ball in my tileset and I just want to add to that ball the exactly same behavior as the mentioned enemy from Technoir: that is, moving horizontally from one wall to another. It hurts you when you touch it, you can kill it. Pretty plzzz?

Quote:
If butterflies count. This question looks unclear to me because you appear to be specifically asking for modifying JJ2 and not anything related to scripting, and this is essentially a scripting thread.
Sorry. I wanted to ask if it's possible to add the new enemies to the system, so they will work in JCS just like the original enemies, so the noobs like me won't have to use any script, will just go to JCS, bring up the enemy list and place them in the level. But you already said that AngelScript does not modify JCS.

Quote:
Yes as long as you aren't specifically asking for 3D bonus stages like those JJ1 has. JJ2 doesn't use gems for anything but points. It was supposed to give you an extra life for every 100 gems but from what I recall they couldn't get the code to work correctly and it was commented out.
No, absolutely no 3D bonuses. Just a regular JJ2 level which is entered like a bonus (that is, after collecting something in the previous level, at the end of that level it warps you to the bonus level).

Quote:
It already does.
Maybe I'm tripping, but doesn't the original secret level in Medivo crash in JJ2? I remember that there was something wrong with that.
cooba

JCF Veteran

Joined: Jan 2004

Posts: 7,814

cooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of light

Mar 16, 2014, 10:33 AM
cooba is offline
Reply With Quote
Quote:
Originally Posted by XxMoNsTeRXM View Post
How can I make a Tuf Boss become an enemy?
Code:
void onLevelLoad() {
	jjObjectPresets[OBJECT::TUFBOSS].behavior = BEHAVIOR::WALKINGENEMY;
}
Quote:
Originally Posted by incandescentembers View Post
I know I may be asking for too much, but can any one show me how can I build the easiest enemy that comes to my mind: that spiky ball from Technoir, which just moves from one wall to another. Let's just say that I have a one tile ball in my tileset and I just want to add to that ball the exactly same behavior as the mentioned enemy from Technoir: that is, moving horizontally from one wall to another. It hurts you when you touch it, you can kill it. Pretty plzzz?
Code:
void onLevelLoad() {
	jjObjectPresets[OBJECT::THING].behavior = Spikeball;
}

void Spikeball(jjOBJ@ obj) {
	jjOBJ@ exp;
	switch (obj.state) {
		case STATE::START:
			obj.direction = obj.xSpeed = -2;
			obj.determineCurAnim(ANIM::DESTSCEN, 4);   //32x32 square sprite
			obj.determineCurFrame();
			obj.bulletHandling = HANDLING::HURTBYBULLET;
			obj.playerHandling = HANDLING::ENEMY;
			obj.state = STATE::FLY;
		case STATE::FLY:
			obj.xPos = obj.xPos + obj.xSpeed;
			if (jjMaskedVLine(obj.xSpeed > 0 ? obj.xPos + 16 : obj.xPos - 16, obj.yPos, 1)) {
				obj.direction = obj.xSpeed = -obj.xSpeed;
			}
			jjDrawTile(obj.xPos - 16, obj.yPos - 16, 4);
			break;
		case STATE::KILL:
			@exp = jjObjects[jjAddObject(OBJECT::EXPLOSION, obj.xPos, obj.yPos, obj.objectID, CREATOR::OBJECT)];
			exp.determineCurAnim(ANIM::AMMO, 5);
			jjSample(obj.xPos, obj.yPos, SOUND::COMMON_EXPL_TNT);
			obj.delete();
			break;
	}
}
Quote:
Originally Posted by incandescentembers View Post
Maybe I'm tripping, but doesn't the original secret level in Medivo crash in JJ2? I remember that there was something wrong with that.
See the Multiple Exits example level.
Love & Thunder

JCF Member

Joined: Sep 2011

Posts: 1,101

Love & Thunder has disabled reputation

Apr 12, 2014, 07:40 AM
Love & Thunder is offline
Reply With Quote
Is there a simple way to create a flicker light once a trigger is activated, with the light appearing on top of the tile that the trigger activated?
__________________
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Apr 12, 2014, 04:42 PM
Violet CLM is offline
Reply With Quote
Simplest would probably be to loop through the object list, find OBJECT::TRIGGERSCENERY objects (with whatever other filters you need, like only ones in a certain area or whatever), and obj.lightType = (obj.curFrame == 0) ? LIGHT::NONE : LIGHT::FLICKER; After first setting the intensity, something like jjObjectPresets[OBJECT::TRIGGERSCENERY].light = jjObjectPresets[OBJECT::FLICKERLIGHT].light;
__________________
BadaboomAri

JCF Member

Joined: Sep 2012

Posts: 27

BadaboomAri is doing well so far

May 30, 2014, 05:37 PM
BadaboomAri is offline
Reply With Quote
So I was tweaking around with changing the sprite and energy of some enemies in Castle1 using jjObjectPresets but the script doesn't work. I don't know what the problem is but hope you guys will be able to find a possible solution.

Code:
void onLevelLoad() {
jjObjectPresets[OBJECT::NORMTURTLE].determineCurAnim(ANIM::LORI, 13);
jjObjectPresets[OBJECT::BAT].determineCurAnim(ANIM::JAZZ, 14);
jjObjectPresets[OBJECT::DRAGON].determineCurAnim(ANIM::SPAZ, 5);
}
__________________
Uhm?
Seren

JCF Member

Joined: Feb 2010

Posts: 868

Seren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to all

May 31, 2014, 02:13 AM
Seren is offline
Reply With Quote
A large number of objects, including those you mentioned, contain animation changes within their behavior. Those tend to reference the animation globally rather than relative to the preset one, resulting in the desired animation being displayed either occasionally or never. To reliably and permanently change sprites of such objects, the best way is to modify their behavior. It's technically possible to write a common behavior function for that and I would consider it cleaner but it will be easier to understand if there are separate ones:
Code:
void myTurtle(jjOBJ@ obj) {
	obj.behave(BEHAVIOR::NORMTURTLE, false);
	obj.determineCurAnim(ANIM::LORI, 13);
	obj.draw();
}
void myBat(jjOBJ@ obj) {
	obj.behave(BEHAVIOR::BAT, false);
	obj.determineCurAnim(ANIM::JAZZ, 14);
	obj.draw();
}
void myDragon(jjOBJ@ obj) {
	obj.behave(BEHAVIOR::DRAGON, false);
	obj.determineCurAnim(ANIM::SPAZ, 5);
	obj.draw();
}
Then you assign the behavior to the presets within onLevelLoad:
Code:
jjObjectPresets[OBJECT::NORMTURTLE].behavior = myTurtle;
jjObjectPresets[OBJECT::BAT].behavior = myBat;
jjObjectPresets[OBJECT::DRAGON].behavior = myDragon;
__________________

I am an official JJ2+ programmer and this has been an official JJ2+ statement.
Zerg

JCF Member

Joined: Oct 2010

Posts: 175

Zerg is doing well so far

Jun 18, 2014, 08:08 AM
Zerg is offline
Reply With Quote
I would like to ask, if is it possible to:
a) Make rfs affect only the player who shoots them - rf climbs don't throw others arround.
b) Uses that spawnpoint, which has a free route. (for ex. in a testlayer number 1,3,4 are occupied, so it chooses 2, later 5,6... numbered player)

If one of them is possible, could someone help me out with that?
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jun 18, 2014, 01:26 PM
Violet CLM is offline
Reply With Quote
a) would be something like this:
Code:
void onMain() {
	for (int i = 1; i < jjObjectMax: ++i) {
		jjOBJ@ obj = jjObjects[i];
		if (obj.behavior == BEHAVIOR::RFBULLET && obj.state == STATE::EXPLODE && !jjPlayers[obj.creatorID].isLocal) //RF missiles, like most/all bullets, switch to STATE::EXPLODE in one gametick and actually run their explosion code in the next, so you have a chance to find them.
			obj.delete(); //Or whatever. Changing its behavior to EXPLOSION or EXPLOSION2 might be good for showing its .killAnim animation, but the point is you don't want it to run its own death code and create a shockwave
	}
}
b) I'm not sure I understand. "spawnpoint"? "free route"?
__________________
Zerg

JCF Member

Joined: Oct 2010

Posts: 175

Zerg is doing well so far

Jun 21, 2014, 11:55 AM
Zerg is offline
Reply With Quote
Thank you for a).
I meant Start Position(Jazz/Spaz level start event). Like if they were numbered, the same as players are when they join a game. So When the player joins, it is placed to the same numbered event, as he/she has(actually order doesn't matter to me).
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jun 21, 2014, 12:12 PM
Violet CLM is offline
Reply With Quote
Got it. What I'd probably do would be use warp targets instead of start positions, each of a different ID 0-31. (Or 200-231 or whatever, if you wanted to include an offset so that you didn't accidentally use the same ID somewhere in the level.) Then given a jjPLAYER@ play, play.warpToID(play.playerID).

You certainly could use start positions, and do a loop through the level using jjEventGet in search of each one, then break; when you find the playerIDth such event. Warp targets would just be easier. Up to you.
__________________
GLaDOS

JCF Member

Joined: Aug 2010

Posts: 40

GLaDOS is doing well so far

Jul 3, 2014, 12:16 PM
GLaDOS is offline
Reply With Quote
What ways of sending information from the server to clients are there with AngelScript? I need to synchronize team ownership and capture progress of control points for a custom gamemode, and I'm currently using the /trigger command to transfer booleans to all clients, but switching those creates unavoidable "Trigger X has been ENABLED" messages, and I cannot send integer values that way.

I looked through all examples and several levels that use AngelScript, but most multiplayer scripts seem to have primarily local effects.

Are there any other values that JJ2+ currently synchronizes (preferrably without side effects) that I'm missing here?
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jul 3, 2014, 01:18 PM
Violet CLM is offline
Reply With Quote
You can get a lot of mileage out of jjPLAYER::fireBullet.

(Obviously this is a domain that'll be much better next update.)
__________________
GLaDOS

JCF Member

Joined: Aug 2010

Posts: 40

GLaDOS is doing well so far

Jul 3, 2014, 01:35 PM
GLaDOS is offline
Reply With Quote
Ah, I'll try this one, thank you very much!
AvalancheMaster

JCF Member

Joined: Sep 2013

Posts: 89

AvalancheMaster is doing well so far

Jul 16, 2014, 05:01 PM
AvalancheMaster is offline
Reply With Quote
Hey, guys, I have some questions, all of which fall under one category, namely: I can't quite understand the way AS refers to objects. If I change an object behavior, would it change just for one instance of the object, for every instance created after the change, or for all instances? Here are some of the things I'm trying to achieve, bear in mind that I have very basic programming skills (some C++, some BASIC, some Python and a lil' bit of WarCraft 3 JASS):

1. How can I palshift the colors of all instances of an object, namely snow? I'm using a modified (through AS) version of Blade's FoFS tileset, and the dirt uses the same gradient as the "dirt", as seen below. I want to shift it to the "grass" (144-159) range.



2. A more complex question: how can I create a basic walking enemy that uses Jazz' stoned sprites, but with changed colors?

3. Is it possible to rotate the texture of the textured background by 90 degrees?

4. Just an additional question to Violet, is it feasible to use different J2A file through AS? I know it's not a CURRENTLY AVAILABLE option, I'm asking if it's a possible one. Of course, the palette should match the original Jazz palette.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jul 16, 2014, 07:33 PM
Violet CLM is offline
Reply With Quote
Quote:
Originally Posted by AvalancheMaster View Post
If I change an object behavior, would it change just for one instance of the object, for every instance created after the change, or for all instances?
It depends on what you mean by "change an object behavior." Whenever an object is added (through jjAddObject or by some bit of native code), the contents of the corresponding jjObjectPresets entry are memcpy'd into a slot in jjObjects. So if you make a change to an object in jjObjects, it'll affect only that one object; if you make a change to an object in jjObjectPresets, it'll affect every object created from that preset after that point, but not any objects that were already created. (The same applies to nearly any other object property, except for the few that get set as part of adding an object like xOrg or creatorType.)
Code:
jjOBJ@ donutPreset = jjObjectPresets[OBJECT::DONUT];
jjOBJ@ donut1 = jjObjects[jjAddObject(OBJECT::DONUT, 0, 0)];
//donutPreset.behavior == donut1.behavior == BEHAVIOR::PICKUP

donutPreset.behavior = BEHAVIOR::MONITOR;
//now donutPreset's behavior is MONITOR, but donut1's behavior is still PICKUP

jjOBJ@ donut2 = jjObjects[jjAddObject(OBJECT::DONUT, 0, 0)];
//donut2 is copied from donutPreset, so donut2's behavior is also MONITOR

donut1.behavior = BEHAVIOR::CRATE;
//only donut1's behavior is changed by this, and subsequently added donuts will continue to use MONITOR, not CRATE, unless...

jjOBJ@ donut3 = jjObjects[jjAddObject(OBJECT::DONUT, 0, 0, 0, CREATOR::OBJECT, BEHAVIOR::PADDLE)];
//donut3's behavior is PADDLE, not MONITOR, because that was explicitly provided in the jjAddObject call. This option is provided because jjAddObject calls the object's behavior function before you get a chance to initialize any of its other properties, and sometimes you might want to circumvent that.
What's important to understand is that nothing separates one object from another besides its properties, almost every one of which you can set in AS. (The only exceptions are objectID, for obvious reasons, and another two bytes which are only used while loading the level but never again.) If jjObjects[1] is a lizard, and you change its eventID and behavior and curAnim and so on, once you've changed enough properties, there will be no respect in which it is still a lizard.

After that I have some bad news for you...

Quote:
1. How can I palshift the colors of all instances of an object, namely snow? I'm using a modified (through AS) version of Blade's FoFS tileset, and the dirt uses the same gradient as the "dirt", as seen below. I want to shift it to the "grass" (144-159) range.
Not in 4.3.
Quote:
2. A more complex question: how can I create a basic walking enemy that uses Jazz' stoned sprites, but with changed colors?
Not in 4.3. Well, you could use SPRITE::PALSHIFT, but it doesn't work with leftward facing sprites, and SPRITE::PLAYER would require that there actually be a player with the colors you want.
Quote:
3. Is it possible to rotate the texture of the textured background by 90 degrees?
Not in 4.3.
Quote:
4. Just an additional question to Violet, is it feasible to use different J2A file through AS? I know it's not a CURRENTLY AVAILABLE option, I'm asking if it's a possible one. Of course, the palette should match the original Jazz palette.
Completely possible. For example, we use native JJ2 code to read from plus.j2d, changing the string embedded in Jazz2+.exe to read "plus.j2d" instead of "data.j2d" before the function gets called, and the same approach could be used for .j2a files too if that seemed like a good idea.
__________________

Last edited by Violet CLM; Jul 16, 2014 at 07:45 PM.
AvalancheMaster

JCF Member

Joined: Sep 2013

Posts: 89

AvalancheMaster is doing well so far

Jul 17, 2014, 04:59 AM
AvalancheMaster is offline
Reply With Quote
Thanks for the answer.

A quick note: I meant that the snow uses the same palette entries as dirt, not dirt.

Quote:
Originally Posted by Violet CLM View Post
It depends on what you mean by "change an object behavior."
I want to change the behaviour of some enemies (though it seems that with the option for using palshifted jazz sprites gone, this one is off the list), and, more importantly, bullets & ammo pickups. Fastfire gives blaster ammo + fastfire, bouncers gives ammo + increased range, ice gives ammo + increased duration of freeze, and so on.

A minor change that I want to achieve is pal-shift some of the enemies, but if I understand correctly, you can palshift the whole image, and not some of the palette entries it uses.

Quote:
Not in 4.3. Well, you could use SPRITE::PALSHIFT, but it doesn't work with leftward facing sprites, and SPRITE::PLAYER would require that there actually be a player with the colors you want.
Woah. That's sad and unexpected. Why leftwards facing sprites are any different?

Quote:
Completely possible. For example, we use native JJ2 code to read from plus.j2d, changing the string embedded in Jazz2+.exe to read "plus.j2d" instead of "data.j2d" before the function gets called, and the same approach could be used for .j2a files too if that seemed like a good idea.
A future release? Or too much work?

Quote:
Not in 4.3.
Considered for next releases?

Those questions aside, it's good that LGR made this review, cause it made me come back to JJ2 (and finish stuff I was already working on). Which then made me realise that I have a ton of BG Warp suitable textures that might be useful for a next release. And I do mean "a ton".

Seren

JCF Member

Joined: Feb 2010

Posts: 868

Seren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to all

Jul 17, 2014, 06:31 AM
Seren is offline
Reply With Quote
Violet's answers are perfectly correct in a way but I wanted to elaborate on the first point.
Quote:
Originally Posted by AvalancheMaster View Post
1. How can I palshift the colors of all instances of an object, namely snow? I'm using a modified (through AS) version of Blade's FoFS tileset, and the dirt uses the same gradient as the "dirt", as seen below. I want to shift it to the "grass" (144-159) range.
This is a complex question and I'm going to split it. How can you palshift the colors of all instances of an object? This is not too difficult. In most cases, all you have to do is change their preset's behavior to something like this on level load:
Code:
void newBehavior(jjOBJ@ obj) {
  obj.behave(BEHAVIOR::oldBehavior, false);
  jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PALSHIFT, value);
}
where the parts in red should be replaced by appropriate identifiers / literals.

Now, getting to the "namely snow" part; this doesn't solve your problem because you seem to have gotten it wrong. Snow instances are not objects. Or, to be unambiguous, they are not jjOBJ instances. They are particles, i.e. jjPARTICLE instances. As such, their options are much more limited. The main problem, as you can imagine, is that you cannot change their behavior. This is a major obstacle but can be overcome by creating snow that is either stored in jjOBJ instances or, preferably, instances of a custom class created for it. In either case you would need to know the default behavior of snow instances, which I believe I'm allowed to provide, and base the new one on that, and that would essentially do the trick, but you would have to prepare to face another problem - this time of much more prosaic nature. You said "144-159". You should be informed that the default snow sprite uses entries 128-136 and entry 201. I suspect that last one could, depending on the exact palette, force a change in your plans.

Anyway, the point is, although it requires an inadequate amount of effort, applying PALSHIFT to snowflakes is essentially possible.
__________________

I am an official JJ2+ programmer and this has been an official JJ2+ statement.
Seren

JCF Member

Joined: Feb 2010

Posts: 868

Seren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to allSeren is a name known to all

Jul 17, 2014, 11:07 AM
Seren is offline
Reply With Quote
Here's the kind of code I meant:
Code:
interface Iparticle {
	void draw(jjCANVAS@) const;
	bool process();
}
class Tsnowflake : Iparticle {
	private float x, y, xSpeed, ySpeed;
	private uint8 frame;
	private int deathCounter, noClipCounter, speedModifier;
	Tsnowflake(float xPos, float yPos) {
		x = xPos;
		y = yPos;
		uint random = jjRandom();
		xSpeed = -0.5f - (random & 4095) / 16384.f;
		ySpeed = ((random >>= 12) & 8191) / 4096.f;
		frame = (random >>= 13) & 7;
		deathCounter = 0;
		noClipCounter = 35;
		speedModifier = ((random >> 3) & 15) << 6;
	}
	void draw(jjCANVAS@ canvas) const override {
		canvas.drawSprite(int(x), int(y), ANIM::SNOW, 0, frame, 0, SPRITE::PALSHIFT, 16);
	}
	bool process() override {
		if (deathCounter == 0) {
			uint random = jjRandom();
			x += xSpeed += (int(random & 1023) - 511) / 65536.f + jjSin(jjGameTicks + speedModifier) / 128.f;
			y += ySpeed += ((random >> 16) & 1023) / 65536.f;
			if (noClipCounter > 0)
				noClipCounter--;
			else if (jjMaskedPixel(int(x), int(y)))
				deathCounter = 1;
		} else {
			if (++deathCounter & 7 == 0 && frame < 7)
				frame++;
			if (deathCounter > 70)
				return false;
		}
		for (int i = 0; i < jjLocalPlayerCount; i++) {
			const jjPLAYER@ player = jjLocalPlayers[i];
			if (x + 32 < player.cameraX || y + 32 < player.cameraY || x - 32 >= player.cameraX + jjSubscreenWidth || y - 32 >= player.cameraY + jjSubscreenHeight)
				continue;
			return true;
		}
		return false;
	}
}
array<Iparticle@> particles;
void addSnow() {
	for (int i = 0; i < jjLocalPlayerCount; i++) {
		const jjPLAYER@ player = jjLocalPlayers[i];
		uint random = jjRandom();
		float x = player.cameraX - 32 + player.xSpeed + ((random & 0xFFFF) * (jjResolutionWidth + 64) >> 16);
		float y = player.cameraY - 32 + (((random >> 16) & 0xFFFF) * jjResolutionHeight >> 16);
		particles.insertLast(Tsnowflake(x, y));
	}
}
void drawParticleSet(const array<Iparticle@> &in particleSet, jjCANVAS@ canvas) {
	for (uint i = 0; i < particleSet.length(); i++) {
		particleSet[i].draw(canvas);
	}
}
void processParticleSet(array<Iparticle@>& particleSet) {
	for (uint i = 0; i < particleSet.length();) {
		if (particleSet[i].process())
			i++;
		else
			particleSet.removeAt(i);
	}
}
void onDrawLayer4(jjPLAYER@, jjCANVAS@ canvas) {
	drawParticleSet(particles, canvas);
}
void onLevelLoad() {
	jjObjects[0].determineCurAnim(ANIM::SNOW, 0, false);
}
void onMain() {
	addSnow();
	processParticleSet(particles);
}
The number in red should be modified to the palshift parameter value you want to use. Notice this code doesn't require a snow event in the level.
__________________

I am an official JJ2+ programmer and this has been an official JJ2+ statement.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jul 17, 2014, 02:39 PM
Violet CLM is offline
Reply With Quote
SE makes an excellent point re: drawing snow through direct drawSprite calls.

Quote:
Originally Posted by AvalancheMaster View Post
more importantly, bullets & ammo pickups. Fastfire gives blaster ammo + fastfire, bouncers gives ammo + increased range, ice gives ammo + increased duration of freeze, and so on.
Ah. For that you want to define an onObjectHit hook (scroll up a little from the anchor), and additionally jjObjectPresets[OBJECT::FASTFIRE].scriptedCollisions = true; and again for other pickups that you also want to modify in this way.
Quote:
Woah. That's sad and unexpected. Why leftwards facing sprites are any different?
Each of the different SPRITE::Mode constants refers to a distinct set of drawing functions with distinct purposes in the game. Most are used for drawing ingame objects, but RESIZED is only used for stuff like 3D spike bolls, which never need to be horizontally flipped, and PALSHIFT is only used for colored text as caused by | or # characters, and text is never flipped.


We're staying largely mum about what 5.0 will or won't be able to do, so that people will take the time to do cool stuff with 4.3 instead of waiting around patiently for another set of functions to become available, and then another after that, and then another after that... this is planned to change in August, though, as the hype machine warms up again and we look for a release date.
__________________
Reply

Tags
angelscript, code, jcs, request

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump

All times are GMT -8. The time now is 03:03 PM.