Downloads containing MelkReskins.mut

Downloads
Name Author Game Mode Rating
JJ2+ Only: Capture the Cow Violet CLM Mutator N/A Download file

File preview

#pragma name "Capture the Cow"
#pragma require "MelkCow.png"
#pragma require "MelkIcons.png"
#pragma require "MelkGehakt.png"
#pragma offer "COW_1.WAV"

int cowFirstFrame, grinderFirstFrame, iconFirstFrame;
uint8 cowMappingID, grinderMappingID;

bool canSpawnMilkPickups;
bool mooLoaded;

array<array<uint16>> Grinders;

void onLevelLoad() {
	uint8 customAnimSetID = 0;
	while (jjAnimSets[ANIM::CUSTOM[customAnimSetID]] != 0)
		++customAnimSetID;
	cowFirstFrame = jjAnimations[jjAnimSets[ANIM::CUSTOM[customAnimSetID]].load(jjPIXELMAP("MelkCow.png"), 167, 128, 2,2)];
	while (jjAnimSets[ANIM::CUSTOM[customAnimSetID]] != 0)
		++customAnimSetID;
	grinderFirstFrame = jjAnimations[jjAnimSets[ANIM::CUSTOM[customAnimSetID]].load(jjPIXELMAP("MelkGehakt.png"), 314, 200, 2,2)];
	while (jjAnimSets[ANIM::CUSTOM[customAnimSetID]] != 0)
		++customAnimSetID;
	iconFirstFrame = jjAnimations[jjAnimSets[ANIM::CUSTOM[customAnimSetID]].load(jjPIXELMAP("MelkCowIcons.png"), 47, 43)];
	
	for (uint i = 0; i < 6; ++i)
		jjAnimFrames[cowFirstFrame + i].hotSpotY = -jjAnimFrames[cowFirstFrame + i].height + 20;
	for (uint i = 0; i < 6; ++i)
		jjAnimFrames[grinderFirstFrame + i].hotSpotY -= 72;

	jjPAL pal;
	pal.load("MelkCow.png");
	jjSpriteModeSetMapping(cowMappingID = jjSpriteModeFirstFreeMapping(), array<uint8>={}, pal); 
	pal.load("MelkGehakt.png");
	jjSpriteModeSetMapping(grinderMappingID = jjSpriteModeFirstFreeMapping(), array<uint8>={}, pal);

	jjObjectPresets[OBJECT::CTFBASE].behavior = Cow;
	
	for (int playerID = 0; playerID < 32; ++playerID)
		TracesPerPlayer[playerID].resize(16);
	
	canSpawnMilkPickups = jjObjectPresets[OBJECT::MILK].playerHandling == HANDLING::PICKUP && !jjObjectPresets[OBJECT::MILK].scriptedCollisions;
	
	mooLoaded = jjSampleLoad(SOUND::DOG_WAF1, "COW_1.WAV");
	
	for (int x = jjLayerWidth[4] - 1; --x >= 0;)
	for (int y = jjLayerHeight[4] - 1; --y >= 0;) {
		const auto e = jjEventGet(x,y);
		if (e == AREA::EOL || e == AREA::WARPEOL) {
			auto otherE = jjEventGet(x + 1, y);
			if (e == otherE)
				continue;
			otherE = jjEventGet(x, y + 1);
			if (e == otherE)
				continue;
			otherE = jjEventGet(x + 1, y + 1);
			if (e == otherE)
				continue;
			Grinders.insertLast(array<uint16> = {x * 32 + 15,y * 32 + 15});
		}
	}
	
	array<uint8> recolor(256);
	for (uint i = 64; i <= 79; ++i)
		recolor[i] = jjPalette.color[i].getLight() / 2;
	jjANIMATION@ gem = jjAnimations[jjObjectPresets[OBJECT::REDGEM].curAnim];
	jjANIMFRAME@ frame = jjAnimFrames[gem];
	jjPIXELMAP(jjAnimFrames[jjObjectPresets[OBJECT::MILK].curFrame]).recolor(recolor).save(frame);
	gem.frameCount = 1;
	frame.hotSpotX = int(frame.width) / -2;
	frame.hotSpotY = int(frame.height) / -2;
	
	jjSetWaterGradient(jjPALCOLOR(255,255,255), jjPALCOLOR(255,255,255)); //milky
}

void onLevelBegin() {
	jjSugarRushAllowed = true;
}

void Cow(jjOBJ@ obj) {
	if (obj.var[4] != 0 && canSpawnMilkPickups) {
		if (obj.counter == 20) {
			if (jjLocalPlayers[0].isInGame && (jjLocalPlayers[0].teamRed == (obj.var[1] == 1)))
				for (int i = 0; i < 5; ++i) {
					jjOBJ@ milk = jjObjects[jjAddObject(OBJECT::MILK, obj.xOrg, obj.yOrg - 60, 0,CREATOR::OBJECT, BEHAVIOR::BIRDFEATHER)];
					milk.behavior = jjObjectPresets[OBJECT::FLICKERGEM].behavior;
					milk.state = STATE::FLOATFALL;
					milk.playerHandling = HANDLING::DELAYEDPICKUP;
					milk.counter = 8 * 70;
				}
			jjAddParticlePixelExplosion(obj.xOrg, obj.yOrg - 60, cowFirstFrame, obj.direction, 0); //yeah the colors aren't right but whatever
		} else if (obj.counter == 1) {
			jjSample(obj.xOrg, obj.yOrg, SOUND::COMMON_COLLAPS, 60, 7000);
		} else if (obj.counter == 40) {
			if (mooLoaded)
				jjSample(obj.xOrg, obj.yOrg, SOUND::DOG_WAF1);
		}
	}
	obj.behave(BEHAVIOR::FLAG, jjColorDepth == 8);
	if (jjColorDepth == 8)
		return;
	const int direction = obj.var[2] == 1 ? -1 : 1;
	const uint8 color = obj.var[1] == 1 ? 44 : 35;
	jjDrawSpriteFromCurFrame(obj.xOrg, obj.yOrg, grinderFirstFrame + (obj.var[4] != 0 ? ((obj.counter / 4) % 6) : 0), direction, SPRITE::MAPPING, grinderMappingID);
	if (obj.state == STATE::SLEEP) {
		const auto cowX = obj.xOrg - 75 * direction;
		jjDrawSpriteFromCurFrame(cowX, obj.yOrg, cowFirstFrame + 1 + ((jjGameTicks / 7) % 5), direction, SPRITE::MAPPING, cowMappingID);
		jjDrawSpriteFromCurFrame(cowX, obj.yOrg - 70, iconFirstFrame, 1, SPRITE::TRANSLUCENTCOLOR, color);
		jjDrawSpriteFromCurFrame(cowX, obj.yOrg - 70, iconFirstFrame + 1);
	}
	jjDrawSpriteFromCurFrame(obj.xOrg, obj.yOrg - 100, iconFirstFrame, 1, SPRITE::TRANSLUCENTCOLOR, color);
	jjDrawSpriteFromCurFrame(obj.xOrg, obj.yOrg - 100, iconFirstFrame + 1);
}

class Trace {
	int16 xPos, yPos;
	int8 direction;
	Trace(){}
	void assign(uint16 x, uint16 y, int8 d) { xPos = x; yPos = y; direction = d; }
}
void onMain() {
	for (int playerID = 0; playerID < 32; ++playerID) {
		const jjPLAYER@ player = jjPlayers[playerID];
		Trace@ trace = TracesPerPlayer[playerID][jjGameTicks & 15];
		trace.assign(int16(player.xPos), int16(player.yPos), player.direction);
	}
}
array<array<Trace>> TracesPerPlayer(32);
array<bool> PlayerHadACow(32, false);
void onPlayerDraw(jjPLAYERDRAW& draw) {
	const jjPLAYER@ player = draw.player;
	const int playerID = player.playerID;
	const bool wasCarrying = PlayerHadACow[playerID];
	if (jjGameMode == GAME::CTF)
		PlayerHadACow[playerID] = draw.flag != TEAM::NEUTRAL;
	else if (jjGameCustom == GAME::RT)
		PlayerHadACow[playerID] = player is jjTokenOwner;
	else if (jjGameMode == GAME::TREASURE)
		PlayerHadACow[playerID] = (player.gems[GEM::RED] + player.gems[GEM::GREEN] * 5 + player.gems[GEM::BLUE] * 10 + player.gems[GEM::PURPLE]) >= jjMaxScore;
	
	if (!PlayerHadACow[playerID] || jjColorDepth == 8)
		return;
	
	draw.flag = TEAM::NEUTRAL;
	if (!wasCarrying && mooLoaded)
		jjSample(player.xPos, player.yPos, SOUND::DOG_WAF1);
	Trace@ trace = TracesPerPlayer[playerID][(jjGameTicks + 1) & 15];
	jjDrawSpriteFromCurFrame(trace.xPos, trace.yPos, cowFirstFrame, trace.direction, SPRITE::MAPPING, cowMappingID, layerZ: draw.layer);
	jjDrawSpriteFromCurFrame(
		player.xPos, player.yPos - 70, iconFirstFrame, 1, SPRITE::TRANSLUCENTCOLOR,
		jjGameMode == GAME::CTF ? (player.teamRed ? 44 : 35) :
		jjGameCustom == GAME::RT ? 17 :
		/*jjGameMode == GAME::TREASURE ? */50,
		layerZ: -100
	);
	jjDrawSpriteFromCurFrame(player.xPos, player.yPos - 70, iconFirstFrame + 1, layerZ: -100);
}

void onDrawLayer4(jjPLAYER@, jjCANVAS@ canvas) {
	if (jjGameMode == GAME::TREASURE && jjColorDepth != 8)
		for (uint i = 0; i < Grinders.length; ++i) {
			auto position = Grinders[i];
			canvas.drawSpriteFromCurFrame(position[0], position[1], grinderFirstFrame, 1, SPRITE::MAPPING, grinderMappingID);
		}
}