Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Race.mut | PurpleJazz | Mutator | N/A |
#pragma name "Race.mut"
class warp {
int xTile, yTile;
}
array<warp> Warps;
uint lapDelay = 0;
array<uint64> lapTimes(0, 0);
array<uint> laps(0, 0);
uint64 currLapTime = 0;
uint64 totalLapTime = 0;
array<uint64> bestLapTime(1, 25200);
string formatTime(uint64 time) {
return (time / (70 * 60)) + ':' + formatInt(time / 70 % 60, '0', 2) + ':' + formatInt(time * 100 / 7 % 1000, '0', 3);
}
array<string> positions = {"1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", "30th", "31st", "32nd"};
uint playerPosition = 0;
array<bool> hasFinished(32, false);
array<string> playerRanking(32, "1st");
bool finished = false;
bool onLastLap = false;
bool raceNotStarted = false;
float cameraX = 0;
float cameraY = 0;
bool pressOnce = false;
class Waypoint {
float xPos, yPos;
}
array<Waypoint> Waypoints;
void onLevelLoad() {
jjAnimSets[ANIM::BRIDGE].load();
//jjObjectPresets[OBJECT::BOUNCEONCE].behavior = Waypoint();
}
void onLevelBegin() {
for (int x = 0; x < jjLayerWidth[4]; x++) {
for (int y = 0; y < jjLayerHeight[4]; y++) {
if (jjEventGet(x, y) == AREA::WARP && jjParameterGet(x, y, 16, 1) == 1) {
warp Finish;
Finish.xTile = x;
Finish.yTile = y;
Warps.insertLast(Finish);
}
}
}
cameraX = jjLocalPlayers[0].xPos;
cameraY = jjLocalPlayers[0].yPos;
if (jjIsServer) {
if (jjEventGet(0, 0) == 255 && jjParameterGet(0, 0, 0, 5) > 0) {
int maxLap = jjParameterGet(0, 0, 0, 8);
if (jjMaxScore != maxLap) jjChat("/maxscore " + maxLap);
}
}
for (int i = 0; i < jjLocalPlayerCount; i++) {
jjLocalPlayers[i].score = 1;
}
}
void onPlayer(jjPLAYER@ play) {
if ((jjGameState == GAME::STOPPED || jjGameState == GAME::PREGAME) && jjGameTicks == 2) raceNotStarted = true;
if (jjIsServer && jjGameTicks == 2) updateName(play, play.score, (play.score <= jjMaxScore? false:true), playerRanking[play.playerID]);
if (raceNotStarted) {
if (jjGameState == GAME::STARTED) {
play.cameraUnfreeze(true);
raceNotStarted = false;
play.invisibility = false;
play.noFire = false;
play.xPos = play.xOrg;
play.yPos = play.yOrg;
play.blink = 70;
} else {
play.xPos = 0;
play.yPos = 0;
play.keyJump = play.keyRun = false;
if (!play.isConnecting) play.noFire = true;
play.buttstomp = 121;
play.invisibility = true;
play.cameraFreeze(cameraX, cameraY, true, jjGameTicks <= 2? true:false);
if (!play.keyLeft && !play.keyRight && !play.keyUp && !play.keyDown) {
if (jjKey[0x01]) {
cameraX = jjMouseX + play.cameraX;
cameraY = jjMouseY + play.cameraY;
}
}
if (play.keyLeft && cameraX > 0) cameraX -= 16;
else if (play.keyRight && cameraX < jjLayerWidth[4]*32) cameraX += 16;
if (play.keyUp && cameraY > 0) cameraY -= 16;
else if (play.keyDown && cameraY < jjLayerHeight[4]*32) cameraY += 16;
}
}
if (jjKey[0x02]) {
if (!pressOnce) {
Waypoint newWaypoint;
newWaypoint.xPos = jjMouseX + play.cameraX;
newWaypoint.yPos = jjMouseY + play.cameraY;
Waypoints.insertLast(newWaypoint);
pressOnce = true;
}
} else {
pressOnce = false;
}
if (jjKey[0x2E]) {
for (uint i = 1; i < Waypoints.length(); i++) {
Waypoints.removeAt(i);
}
}
if (play.health > 0 && play.health < jjMaxHealth) play.health = jjMaxHealth; //immortality from weapons
if ((jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME) && !finished && !play.isSpectating && !play.isIdle) {
totalLapTime++;
currLapTime++;
}
for (uint i = 0; i < Warps.length(); i++) {
warp@ Finish = Warps[i];
if ((int(play.xPos)/32 == Finish.xTile && int(play.yPos)/32 == Finish.yTile) && play.score <= (jjMaxScore+1)) {
if (lapDelay == 0) {
play.score++;
lapDelay = 140;
if (play.score <= (jjMaxScore+1)) lapTimes.insertLast(currLapTime);
updateName(play, play.score, (play.score <= jjMaxScore? false:true), playerRanking[play.playerID]);
if (!jjIsServer) {
if (play.score <= (jjMaxScore+1)) {
jjSTREAM packet;
packet.push(play.score);
packet.push(totalLapTime);
uint64 lapTime = currLapTime;
packet.push(lapTime);
jjSendPacket(packet);
}
} else {
if (currLapTime < bestLapTime[0] && play.score > 1 && play.score <= (jjMaxScore+1)) {
bestLapTime.insertLast(currLapTime);
array<string> results;
string name = play.nameUnformatted;
while (jjRegexMatch(name, """(.*)\[(1?\d{1,2}|1st|2nd|3rd|4th|5th|6th|7th|8th|9th|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|30th|31st|32nd)\](\|*\*)?""", results)) {
name = results[1];
jjAlert("|||" + name + " has set a new best lap time of " + formatTime(currLapTime) + "!", true, STRING::SMALL);
}
}
}
} else if (lapDelay == 138) {
currLapTime = 0;
laps.insertLast(play.score - 1);
}
}
}
if (lapDelay > 0) lapDelay--;
if (play.score == jjMaxScore) {
setFinishWarp();
}
if (play.warpID == 256 && jjGameTicks > 2 && play.score <= (jjMaxScore+1)) {
if (!jjIsServer) {
if (lapDelay == 140 && play.score <= (jjMaxScore+1)) {
jjSTREAM packet;
packet.push(play.score);
packet.push(totalLapTime);
uint64 lapTime = currLapTime;
packet.push(lapTime);
jjSendPacket(packet);
}
} else {
if (!hasFinished[play.playerID] && play.score <= (jjMaxScore+1)) {
array<string> results;
string name = play.nameUnformatted;
while (jjRegexMatch(name, """(.*)\[(1?\d{1,2}|1st|2nd|3rd|4th|5th|6th|7th|8th|9th|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|30th|31st|32nd)\](\|*\*)?""", results)) {
name = results[1];
jjAlert("|||" + name + " has finished in " + positions[playerPosition] + " place! (" + formatTime(totalLapTime) + ")", true, STRING::SMALL);
}
playerPosition++;
hasFinished[play.playerID] = true;
updateName(play, play.score, (play.score <= jjMaxScore? false:true), positions[playerPosition-1]);
}
}
finished = true;
}
if (jjIsServer) bestLapTime.sortAsc();
}
void setFinishWarp() {
if (!onLastLap) {
for (int x = 0; x < jjLayerWidth[4]; x++) {
for (int y = 0; y < jjLayerHeight[4]; y++) {
if (jjEventGet(x, y) == AREA::WARP && jjParameterGet(x, y, 16, 1) == 1 && jjParameterGet(x, y, 0, 8) != 255) {
jjParameterSet(x, y, 0, 8, 255);
}
}
}
onLastLap = true;
}
}
void onMain() {
if (jjIsServer) {
for (int i = 1; i < 32; i++) {
jjPLAYER@ play = jjPlayers[i];
if (play.isConnecting && play.isActive) updateName(play, 1, false, "");
}
}
}
void onReceive(jjSTREAM &in packet, int clientID) {
if (jjIsServer) {
int playerLap;
uint64 clientTime;
uint64 clientLapTime;
packet.pop(playerLap);
packet.pop(clientTime);
packet.pop(clientLapTime);
jjPLAYER@ play = jjPlayers[clientID];
play.score = playerLap;
if (!hasFinished[play.playerID] && playerLap > jjMaxScore) {
array<string> results;
string name = play.nameUnformatted;
while (jjRegexMatch(name, """(.*)\[(1?\d{1,2}|1st|2nd|3rd|4th|5th|6th|7th|8th|9th|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|30th|31st|32nd)\](\|*\*)?""", results)) {
name = results[1];
jjAlert("|||" + name + " has finished in " + positions[playerPosition] + " place! (" + formatTime(clientTime) + ")", true, STRING::SMALL);
}
playerPosition++;
hasFinished[play.playerID] = true;
playerRanking[play.playerID] = positions[playerPosition - 1];
}
updateName(play, playerLap, (playerLap <= jjMaxScore? false:true), playerRanking[play.playerID]);
if (clientLapTime < bestLapTime[0] && playerLap > 1) {
bestLapTime.insertLast(clientLapTime);
array<string> results;
string name = play.nameUnformatted;
while (jjRegexMatch(name, """(.*)\[(1?\d{1,2}|1st|2nd|3rd|4th|5th|6th|7th|8th|9th|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|30th|31st|32nd)\](\|*\*)?""", results)) {
name = results[1];
jjAlert("|||" + name + " has set a new best lap time of " + formatTime(clientLapTime) + "!", true, STRING::SMALL);
}
}
}
}
void updateName(jjPLAYER@ play, uint lap, bool finished, string pos) {
array<string> results;
string name = play.nameUnformatted;
while (jjRegexMatch(name, """(.*)\[(1?\d{1,2}|1st|2nd|3rd|4th|5th|6th|7th|8th|9th|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|30th|31st|32nd)\](\|*\*)?""", results)) {
name = results[1];
}
string nick = name;
if (!finished)
nick += ("[" + lap + "]");
else nick += ("[" + pos + "]");
if (play.name != nick)
play.setName(nick);
}
bool onDrawHealth(jjPLAYER@ play, jjCANVAS@ canvas) {
if (!jjLocalPlayers[0].isSpectating && !jjLocalPlayers[0].isIdle) {
if (!raceNotStarted) {
canvas.drawString(8, jjGameMode == GAME::BATTLE? 40 : 68, play.score <= jjMaxScore? "Lap " + play.score + " / " + jjMaxScore : "|Finished!", STRING::MEDIUM, STRING::NORMAL);
canvas.drawString(10, jjGameMode == GAME::BATTLE? 68 : 96, "" + formatTime(totalLapTime), STRING::MEDIUM, STRING::NORMAL);
for (uint i = 0; i < laps.length(); i++) {
canvas.drawString(8, ((jjGameMode == GAME::BATTLE? 98 : 126) + (i * 16)), "||||" + laps[i] + ". " + formatTime(lapTimes[i]), STRING::SMALL, STRING::NORMAL);
}
} else {
canvas.drawString(244 - (jjResolutionWidth <= 640? 80:0), 152, "Race not started yet!", STRING::MEDIUM, STRING::NORMAL);
canvas.drawString(84 - (jjResolutionWidth <= 640? 84:0), 190, "|Use the |||movement keys||||| or |||left click and drag||||| to move the camera", STRING::SMALL, STRING::NORMAL);
canvas.drawString(172 - (jjResolutionWidth <= 640? 80:0), 206, "|Click the |||right mouse button||||| to set ||waypoints", STRING::SMALL, STRING::NORMAL);
canvas.drawString(222 - (jjResolutionWidth <= 640? 80:0), 222, "|Press |||delete||||| to erase all ||waypoints", STRING::SMALL, STRING::NORMAL);
}
}
return true;
}
void onDrawLayer4(jjPLAYER@ play, jjCANVAS@ canvas) {
for (uint i = 0; i < Waypoints.length(); i++) {
Waypoint@ waypoint = Waypoints[i];
jjDrawResizedSprite(waypoint.xPos, waypoint.yPos, ANIM::BRIDGE, 5, 0, 2, 2, SPRITE::NORMAL);
}
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.