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

Renascence: The Last Jackrabbit

PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 4, 2018, 10:44 AM
PT32 is offline
Reply With Quote
Lightbulb Renascence: The Last Jackrabbit

Welp, here I am.

It's been five years since I worked on anything worthwhile, besides a multiplayer level or two that I might get around to finishing someday. For a long time I considered myself done with levelmaking but this spring, the bug bit me again, so here I am.

I'm working on a new singleplayer pack. It's not World of Jazz Part 2 - those files were lost in a transfer between computers, and I'd have to start from scratch. This will be a brand new project built within the growing potential of AngelScript. The pack at present consists of roughly twenty levels and will have a centralized story with some light Lovecraftian elements (as I'm reading Lovecraft these days and find it interesting). Emphasis will be placed on multiple-route gameplay ala Deus Ex, where there is a start and end point and multiple ways to get there. There will also be some world lore which can be discovered by exploring the map and finding things. I'm building the pack gameplay-wise to be playable as Jazz, Spaz or Lori, though storywise I need one thing from AngelScript to make that a certainty. This project may be a standalone or it may be a first installment, depending on how I feel about levelmaking by the time I'm done.

Which brings me to the catch - the project will not be done anytime soon. I've just graduated college and am working on situating myself in the workplace, and I don't know yet how much time I'll be able to devote to the project. I also have other creative endeavors which I put the main part of my time into. For all I know this project might take a year or two, but it might also take five years.

But that's a good thing, because it will give time for things I want for the pack to be brought into existence. I'm not a programmer, and I suck at making tilesets. That's why I decided to post about this project at all - I was hoping that, if anyone was willing, folks could start working on things I'm looking for so that I'll be able to take this project to the places I want to take it. I also wanted this to be an advice thread so I can ask people questions - as of yet I'm not thoroughly acquainted with AngelScript and I'm still learning MLLE, but I'd like to make use of both in a full-fledged singleplayer campaign.

So, what do I need for Renascence: The Last Jackrabbit? Here's my list so far (subject to update):

ANGELSCRIPT:
  • Zero Gravity
  • Location tracking (i.e., an arrow persistently pointing back to the start pos)
  • More turtle enemies (i.e., some of the Jazz1 enemies like Je-Turtles from Turtemple, or brand-new types)
  • Rabbit enemies
  • Mutated monster enemies
  • Water-free zones (i.e., dry land below water level)
  • Layer 1 supersceding the water layer (becuz water annoying that way)
  • Placeable static events of Jazz, Devan, Spaz and Lori
  • Placeable static event of the player character
  • Rabbit civilian NPCs
  • The ability for hostile NPCs to shoot at each other (i.e., Rabbit and Turtle forces in combat)
  • Heat wave visual effects (may already exist, I'm not sure)
  • New weapon types (two I'd like to implement are the firework gun and energy blast from Press Garden, but I'll happily take suggestions for other new weapons, too)
  • Misc. UI display stuff (i.e., text appearing onscreen for an objective, then changing once objective is completed)
  • Elimination of damage knockback

TILESETS
(Both tilesets should have at least one black tile)
  • Ocean-themed tileset with sci-fi facility components
  • Greek-themed tileset with city, woodlands and rabbit statues/architecture


I'm also open to any other suggestions or ideas folks might have to help me make this project even better.

As a proof of concept, I've included some very early-production screencaps:







Thanks for your time.

Last edited by PT32; Jul 4, 2018 at 10:57 AM.
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 4, 2018, 01:02 PM
Violet CLM is offline
Reply With Quote
Hi there! As you say, it's been a while--glad to see you jumping back in.

Quote:
Originally Posted by PT32 View Post
Zero Gravity
Code:
array<float> ZeroGravityVerticalPosition(jjLocalPlayerCount, -1);
void onFunction0(jjPLAYER@ play, bool enableZeroGravity) {
  ZeroGravityVerticalPosition[play.localPlayerID] = enableZeroGravity ? play.yPos : -1;
}
void onPlayer(jjPLAYER@ play) {
  if (ZeroGravityVerticalPosition[play.localPlayerID] != -1) {
    play.yPos = ZeroGravityVerticalPosition[play.localPlayerID];
    play.ySpeed = 0;
  }
}
Quote:
Location tracking (i.e., an arrow persistently pointing back to the start pos)
Look at Operation Cleanup for an example of arrow drawing.
Quote:
More turtle enemies (i.e., some of the Jazz1 enemies like Je-Turtles from Turtemple, or brand-new types)
Jazz 1 Enemies
Quote:
Rabbit enemies
Mutated monster enemies
These are too unspecific for there to be much I can say here. Consult the documentation for jjBEHAVIORINTERFACE I guess?
Quote:
Water-free zones (i.e., dry land below water level)
This can't be done at present, if you mean seeing the standard JJ2 water effect in one part of the screen and a waterless area below it on the same screen, unless you do some tricks with layer order (see below).
Quote:
Layer 1 supersceding the water layer (becuz water annoying that way)
This is the "WaterLayer" setting in the "JJ2+ Properties -> Level Properties" window in MLLE.
Quote:
Placeable static events of Jazz, Devan, Spaz and Lori
Placeable static event of the player character
Rabbit civilian NPCs
I'm interpreting these to all be pretty much the same thing, which looks something like this.
Code:
void onLevelLoad() {
  if (jjAnimSets[ANIM::DEVAN] == 0)
    jjAnimSets[ANIM::DEVAN].load();
  jjOBJ@ eventBeingUsedForNPCsInThisLevel = jjObjectPresets[OBJECT::APPLE]; //or whichever other event, up to you
  eventBeingUsedForNPCsInThisLevel.playerHandling = HANDLING::PARTICLE;
  eventBeingUsedForNPCsInThisLevel.behavior = NPC();
}
class NPC : jjBEHAVIORINTERFACE {
  array PossibleAnimationsForEachCharacter = {jjAnimSets[ANIM::JAZZ] + RABBIT::STAND, jjAnimSets[ANIM::SPAZ] + RABBIT::STAND, jjIsTSF ? jjAnimSets[ANIM::LORI] + RABBIT::STAND : 1, jjAnimSets[ANIM::DEVAN] + 1};
  void onBehave(jjOBJ@ obj) {
    switch (obj.state) {
    case STATE::START:
      obj.curAnim = PossibleAnimationsForEachCharacter[jjParameterGet(uint(obj.xPos) / 32, uint(obj.yPos) / 32, 0, 2)];
      obj.curFrame = jjAnimations[obj.curAnim];
      obj.putOnGround(true);
      obj.var[0] = jjParameterGet(uint(obj.xPos) / 32, uint(obj.yPos) / 32, 2, 5); //which player number to get fur colors from
      obj.state = STATE::IDLE;
      break;
    case STATE::DEACTIVATE:
      obj.deactivate();
      break;
    default: {
      const int nearestPlayerID = obj.findNearestPlayer(128 * 128);
      if (nearestPlayerID >= 0)
        obj.direction = jjPlayers[nearestPlayerID].xPos > obj.xPos ? 1 : -1;
      if (++obj.age == 7) {
        ++obj.frameID;
        obj.determineCurFrame();
        obj.age = 0;
      }
      break; }
    }
  }
  void onDraw(jjOBJ@ obj) {
    jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::PLAYER, obj.var[0]);
  }
}
For defining how your various NPCs should look, you'll want some lines like this in onLevelLoad, where the numbers match up to gradients in the palette:
Code:
jjPlayers[1].furSet(24,32,40,48);
Finally you'll want to edit either MLLEProfile - JJ2.ini or MLLEProfile - TSF.ini, depending, to include this line in the "Events" group:
Code:
141=NPC                              |+|Scenery   |NPC    |     |Character:{Jazz,Spaz,Lori,Devan}2|Fur Colors:5
Quote:
The ability for hostile NPCs to shoot at each other (i.e., Rabbit and Turtle forces in combat)
The difficulty here is you stating the desired behavior clearly enough for it to be translatable into code. "[S]hoot at" is pretty vague and encompasses an infinitely wide range of possible implementations.
Quote:
Heat wave visual effects (may already exist, I'm not sure)
While hovering over a mouse in the Tileset pane of MLLE, press Shift+5.
Quote:
New weapon types (two I'd like to implement are the firework gun and energy blast from Press Garden, but I'll happily take suggestions for other new weapons, too)
You can find most custom weapons under the top gun contest downloads tag.
Quote:
Misc. UI display stuff (i.e., text appearing onscreen for an objective, then changing once objective is completed)
Code:
string CurrentObjective = "Get to the choppa";
bool onDrawScore(jjPLAYER@, jjCANVAS@ canvas) {
  canvas.drawString(10, 50, CurrentObjective);
  return false;
}
and change the value of the CurrentObjective variable when appropriate.
Quote:
Elimination of damage knockback
Code:
array<float> PlayerLastHorizontalSpeed(jjLocalPlayerCount), PlayerLastVerticalSpeed(jjLocalPlayerCount);
array<bool> PlayerWasHurtLastGameTick(jjLocalPlayerCount, false);
void onPlayer(jjPLAYER@ play) {
  const bool playerIsHurt = play.curAnim == jjAnimSets[play.setID] + RABBIT::HURT;
  if (playerIsHurt && !PlayerWasHurtLastGameTick[play.localPlayerID]) {
    play.xSpeed = PlayerLastHorizontalSpeed[play.localPlayerID];
    play.ySpeed = PlayerLastVerticalSpeed[play.localPlayerID];
  } else {
    PlayerLastHorizontalSpeed[play.localPlayerID] = play.xSpeed;
    PlayerLastVerticalSpeed[play.localPlayerID] = play.ySpeed;
  }
  PlayerWasHurtLastGameTick[play.localPlayerID] = playerIsHurt;
}
That's a literal interpretation of the statement, but there's the separate issue that players can't control their rabbits for half a second after they've been hurt, which isn't something you can get rid of as easily. The only alternative I'm thinking of is to have all damage done to the player done by editing jjPLAYER::health from within the script, instead of traditional built-in collision damage from enemies/bullets/hurt events, but that might be a bit more than you want to take on.
Quote:
(Both tilesets should have at least one black tile)
Right-click on a tile in the Tileset pane in MLLE and click "Edit Image..." from the context menu.

If you don't find specific tilesets with all the different components you need, instead you can use the "JJ2+ Properties -> Tilesets -> Add New..." dropdown menu option in MLLE to use tiles from multiple tilesets in a single level.
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 4, 2018, 03:45 PM
PT32 is offline
Reply With Quote
Thanks! That'll give me some great stuff to get started on.
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 5, 2018, 11:03 PM
PT32 is offline
Reply With Quote
Is there a way with Angelscript to carry over coins between levels?
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 6, 2018, 10:23 AM
Violet CLM is offline
Reply With Quote
Sure... but again you have to be careful in how you define the question. How do you want coin saving to interact with dying, the continue screen, loading/saving, skipping levels, playing levels out of order, winning then starting again?
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 6, 2018, 02:37 PM
PT32 is offline
Reply With Quote
My goodness, I didn't realize money was so complicated. Guess I really should have.

I was thinking about having the player accumulate coins from level to level as they go, with opportunities at various points along the way to spend those accumulated coins. For example, Player collects coins in Levels 1-5, then has opportunity to spend them at a bonus warp in Level 6. Player can then begin collecting again, including the excess they had left over from Levels 1-6, to spend coins at a Level 12 Bonus, and so on.

Upon dying, Player would keep the coins they earned in previous levels/save points, but would have to collect "unsaved" coins again.

At the Continue Screen, Player would start over with 0 coins.

If Player saves or loads from a spot in the level, then they have however many coins they saved with. Guess I'm not sure what you're asking with this but maybe I'm just missing something.

If Player skips a level they simply don't get credit for the coins in the level they skipped. Same for if levels played out of order - Player's coin credit carries over from levels if they've played them on this playthrough of the pack. If they jump in on Level 9 or Level 4 or 13 or whatever, their counter starts from that level.

If Player wins and starts again, then they start with 0 coins, as if it's a new playthrough.

One idea I had was doing a Coin reset about halfway through the pack, where the counter resets to 0. This fits well with the story and might/might not help with boondoggles. But now I'm worried if that would just complicate matters more.

Last edited by PT32; Jul 6, 2018 at 02:39 PM. Reason: better explanation derps
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 23, 2018, 10:19 AM
PT32 is offline
Reply With Quote
So I'm reading the walkthrough and trying to wrap my head around how to write AngelScript code, and it's a bit overwhelming. Could I get some laymen's tips on basic syntax and code structure so I can figure it out, get a good grasp on it? For instance, I'd like to generate an AngelScript using this zero gravity snippet Violet provided...

Quote:
Originally Posted by Violet CLM View Post
Code:
array<float> ZeroGravityVerticalPosition(jjLocalPlayerCount, -1);
void onFunction0(jjPLAYER@ play, bool enableZeroGravity) {
  ZeroGravityVerticalPosition[play.localPlayerID] = enableZeroGravity ? play.yPos : -1;
}
void onPlayer(jjPLAYER@ play) {
  if (ZeroGravityVerticalPosition[play.localPlayerID] != -1) {
    play.yPos = ZeroGravityVerticalPosition[play.localPlayerID];
    play.ySpeed = 0;
  }
}
...but because I don't understand the syntax, I don't know how to properly put it into an AngelScript. I'm no good with coding and such so this isn't coming very easily to me.

Thanks!
__________________
Don't say "cannot," say "why not?"

IN DEVELOPMENT:
Renascence: The Last Jackrabbit
PurpleJazz PurpleJazz's Avatar

JCF Member

Joined: Aug 2006

Posts: 852

PurpleJazz is OFF DA CHARTPurpleJazz is OFF DA CHARTPurpleJazz is OFF DA CHART

Jul 23, 2018, 11:36 AM
PurpleJazz is offline
Reply With Quote
Quote:
Originally Posted by PT32 View Post
So I'm reading the walkthrough and trying to wrap my head around how to write AngelScript code, and it's a bit overwhelming. Could I get some laymen's tips on basic syntax and code structure so I can figure it out, get a good grasp on it? For instance, I'd like to generate an AngelScript using this zero gravity snippet Violet provided...



...but because I don't understand the syntax, I don't know how to properly put it into an AngelScript. I'm no good with coding and such so this isn't coming very easily to me.

Thanks!
All you need to do to utilize this script in your level is to place a Text string with the TextID parameter set to 0, the Angelscript parameter to 1 and the Offset parameter set to 1 if you want to enable zero gravity when the player touches this event, or 0 if you want to disable it.
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 23, 2018, 02:58 PM
PT32 is offline
Reply With Quote
Thanks!

What about sound muting? If I wanted a level to just play music and not sound effects, what code would I use?

Also, I am trying to figure out how palette hue shifting works. I want to set a level's palette to be black-and-white, possibly increase the contrast (if possible), but I'm having trouble with the Plus example AngelScript for palette editing.

Also also, I'm trying to figure out how to use new multiple layers (layers past the base 8) in MLLE and I seem to be having difficulty making them show up. Could someone explain that process for me please? It looks like it should be straightforward but when I test the level the new layers don't appear ingame.

Last edited by PT32; Jul 23, 2018 at 05:06 PM. Reason: added requests, post consolidation
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 24, 2018, 10:59 AM
Violet CLM is offline
Reply With Quote
Quote:
Originally Posted by PT32 View Post
What about sound muting? If I wanted a level to just play music and not sound effects, what code would I use?
What you'd need to do here is find a .wav file that makes no sound at all, such as HH17_Null.wav, and use the jjSampleLoad function to replace each sound that might play in the level with that .wav file, one by one.
Quote:
Also, I am trying to figure out how palette hue shifting works. I want to set a level's palette to be black-and-white, possibly increase the contrast (if possible), but I'm having trouble with the Plus example AngelScript for palette editing.
If you want the whole level to use the same palette, instead of worrying about editing it line-by-line in script, I'd recommend either editing the level's palette inside MLLE or else using Palette Suite or some other dedicated program to create a .pal file and then loading that.
Quote:
Also also, I'm trying to figure out how to use new multiple layers (layers past the base 8) in MLLE and I seem to be having difficulty making them show up. Could someone explain that process for me please? It looks like it should be straightforward but when I test the level the new layers don't appear ingame.
It should be straightforward, yes, so some more details about what it is you're doing might help. Are you sure you're running the level in JJ2+, not regular JJ2? Do you have AngelscriptDebug=True in your plus.ini file, and if so, do any error messages appear when you try to test the level?
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 24, 2018, 01:20 PM
PT32 is offline
Reply With Quote
Quote:
Originally Posted by Violet CLM View Post
What you'd need to do here is find a .wav file that makes no sound at all, such as HH17_Null.wav, and use the jjSampleLoad function to replace each sound that might play in the level with that .wav file, one by one.

[...]

It should be straightforward, yes, so some more details about what it is you're doing might help. Are you sure you're running the level in JJ2+, not regular JJ2? Do you have AngelscriptDebug=True in your plus.ini file, and if so, do any error messages appear when you try to test the level?
A) How would I go about formatting the SampleLoad in my AngelScript doc? I assume it's the bool jjSampleLoad function in the AngelScript readme. Is there a specific order it needs to be in relating to other AS functions in my doc?

B) I'm running the level out of MLLE. The game is in JJ2+. I turned AngelScriptDebug on but it doesn't show any error messages - the extra layer/s simply won't display. Is there something special I'm supposed to do for an extra layer, that I wouldn't have to do for a normal layer? I guess I don't know what all the steps are for extra layer creation, so maybe I'm missing something. I assumed you just create the layer and it's supposed to show up.
__________________
Don't say "cannot," say "why not?"

IN DEVELOPMENT:
Renascence: The Last Jackrabbit
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 24, 2018, 09:46 PM
Violet CLM is offline
Reply With Quote
When you call jjSampleLoad, it will affect every time that sample is played thereafter. If you want to prevent the sample from being heard at any point in the level, you should call jjSampleLoad as soon as possible, i.e. somewhere in the onLevelLoad function.

There is nothing special you're supposed to do for extra layers, no. Maybe you have them ordered behind layer 8, so the user can't actually see them? Maybe you have Low Detail turned on?
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 25, 2018, 08:44 AM
PT32 is offline
Reply With Quote
I have two extra layers, they are between Layers 5 and 6. Where do I go to check Low Detail?
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 25, 2018, 10:44 AM
Violet CLM is offline
Reply With Quote
It's in the Video dropdown menu of the JJ2 window, same as it's ever been, but if you can see layers 5 and 6 then you probably don't have Low Detail on.
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Jul 26, 2018, 05:53 AM
PT32 is offline
Reply With Quote
I can see Layers 5 and 6, yes. And no, Low Detail was not turned on.

Do you think it's maybe the MLLE version number? I have 2.9.0.0, the version that was available to download on J2O. Or maybe there's a plugin or something I'm missing. I copied everything in that J2O MLLE folder to my JJ2 directory.

I did notice something odd though. When I go to delete one of the extra layers, it asks if I'm sure I want to delete the contents of the base layer right after it. For example, if Layer 6 is after my extra layer, when I go to delete the extra layer it asks if I'm sure I want to delete the contents of Layer 6. What's even odder is that if I have two extra layers next to each other, the second extra seems to "glue" in this manner to the base layer beyond that, so both Layer 6 and Layer 7. Not sure if this helps but I just noticed it this morning.

Last edited by PT32; Jul 26, 2018 at 06:01 AM. Reason: spaaaaaaace
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Jul 27, 2018, 09:49 AM
Violet CLM is offline
Reply With Quote
The alert for clearing layers probably isn't related. It's probably just a case of that bit of the UI not being updated to reflect the possibility of extra layers.

At this point I really don't know what you're doing wrong from your descriptions. If you're not comfortable sharing the file/s in question or taking screenshots of the relevant MLLE windows, I suggest creating a minimal test case--make a new .j2l just for the sake of experimenting with this issue, try adding an extra layer or two to that, and see how far you get and report on your progress.
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Aug 4, 2018, 02:42 PM
PT32 is offline
Reply With Quote
I believe I've solved the mystery.

Apparently, in order to get extra layers to show up you have to save the level in your JJ2 directory. Not in a separate folder (like where I keep all the levels for this project), but straight in the JJ2 directory. I tried that and the extra layers show up now. I'm guessing it has something to do with the MLLE-data level files?
PurpleJazz PurpleJazz's Avatar

JCF Member

Joined: Aug 2006

Posts: 852

PurpleJazz is OFF DA CHARTPurpleJazz is OFF DA CHARTPurpleJazz is OFF DA CHART

Aug 4, 2018, 03:07 PM
PurpleJazz is offline
Reply With Quote
Quote:
Originally Posted by PT32 View Post
I believe I've solved the mystery.

Apparently, in order to get extra layers to show up you have to save the level in your JJ2 directory. Not in a separate folder (like where I keep all the levels for this project), but straight in the JJ2 directory. I tried that and the extra layers show up now. I'm guessing it has something to do with the MLLE-data level files?
AdditionalFileFolders is your friend (in plus.ini)
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Aug 6, 2018, 02:36 PM
PT32 is offline
Reply With Quote
On to a new subject!
I'm looking for a tileset/s with a suitable book-looking tile, preferably (though I'll make do) lying as if on the ground. There are three types I'm looking for:

1) a conventional, book tile
2) a techy looking data pad tile
3) a more clipboard-looking, industrial-setting tile

Would anyone know of a good tileset/s with these sorts of things? Am open to a variety of options as long as they look reasonably close to book status. I am, after all, judging by cover.
Violet CLM Violet CLM's Avatar

JCF Éminence Grise

Joined: Mar 2001

Posts: 10,978

Violet CLM has disabled reputation

Aug 6, 2018, 05:35 PM
Violet CLM is offline
Reply With Quote
Instead of a tileset, would you settle for search results from OpenGameArt and The Spriters Resource?
__________________
PT32 PT32's Avatar

JCF Member

Joined: Jul 2008

Posts: 274

PT32 is an asset to this forum

Aug 7, 2018, 09:49 AM
PT32 is offline
Reply With Quote
If I could get some instruction on how to integrate said elements into a tileset/level, as I know very little about tilesets, that could work.
Reply

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:05 PM.