Blame heliantus/group.c

8535a3
8535a3
#include "private.h"
8535a3
#include "group.h"
8535a3
#include "world.h"
8535a3
8535a3
struct _Group {
8535a3
	HeliArray sprites;
8535a3
};
8535a3
8535a3
8535a3
Group createGroup() {
8535a3
	Group g = calloc(1, sizeof(*g));
8535a3
	return g;
8535a3
}
8535a3
8535a3
Group createEdgesGroupEx(double x1, double y1, double x2, double y2, double borderWidth) {
8535a3
	if (x2 < x1) { double x = x2; x2 = x1; x1 = x; }
8535a3
	if (y2 < y1) { double y = y2; y2 = y1; y1 = y; }
8535a3
	if (borderWidth < 0.1) borderWidth = 0.1;
8535a3
	
8535a3
	double b = borderWidth;
8535a3
	double w = x2 - x1 + b*2;
8535a3
	double h = y2 - y1 + b*2;
8535a3
	x1 -= b;
8535a3
	y1 -= b;
8535a3
	
8535a3
	Group g = createGroup();
8535a3
	groupAdd(g, createSpriteEx(x1, y1, w, b));
8535a3
	groupAdd(g, createSpriteEx(x1, y2, w, b));
8535a3
	groupAdd(g, createSpriteEx(x1, y1, b, h));
8535a3
	groupAdd(g, createSpriteEx(x2, y1, b, h));
8535a3
	return g;
8535a3
}
8535a3
8535a3
Group createEdgesGroup()
8535a3
	{ return createEdgesGroupEx(0, 0, worldGetWidth(), worldGetHeight(), 10); }
8535a3
8535a3
8535a3
void groupDestroy(Group group) {
8535a3
	heliArrayDestroy(&group->sprites);
8535a3
	free(group);
8535a3
}
8535a3
8535a3
void groupDestroyEx(Group group, int destroySprites) {
8535a3
	groupClearEx(group, destroySprites);
8535a3
	groupDestroy(group);
8535a3
}
8535a3
8535a3
void groupAdd(Group group, Sprite sprite) {
8535a3
	if (groupContains(group, sprite)) return;
8535a3
	heliArrayInsert(&group->sprites, -1, sprite, NULL);
8535a3
	heliArrayInsert(heliSpriteGetGroups(sprite), -1, sprite, NULL);
8535a3
}
8535a3
8535a3
void groupRemove(Group group, Sprite sprite) {
8535a3
	for(int i = group->sprites.count-1; i >= 0; --i)
8535a3
		if (group->sprites.items[i].value == sprite)
8535a3
			heliArrayRemove(&group->sprites, i);
8535a3
	HeliArray *groups = heliSpriteGetGroups(sprite);
8535a3
	for(int i = groups->count-1; i >= 0; --i)
8535a3
		if (groups->items[i].value == group)
8535a3
			heliArrayRemove(groups, i);
8535a3
}
8535a3
8535a3
void groupClearEx(Group group, int destroySprites) {
8535a3
	while(groupGetCount(group) > 0) {
8535a3
		Sprite s = groupGet(group, 0);
8535a3
		groupRemove(group, s);
8535a3
		if (destroySprites) spriteDestroy(s);
8535a3
	}
8535a3
}
8535a3
8535a3
void groupClear(Group group)
8535a3
	{ groupClearEx(group, FALSE); }
8535a3
void groupDestroyEach(Group group)
8535a3
	{ groupClearEx(group, TRUE); }
8535a3
8535a3
int groupContains(Group group, Sprite sprite) {
8535a3
	for(int i = group->sprites.count-1; i >= 0; --i)
8535a3
		if (group->sprites.items[i].value == sprite)
8535a3
			return TRUE;
8535a3
	return FALSE;
8535a3
}
8535a3
8535a3
int groupGetCount(Group group)
8535a3
	{ return group->sprites.count; }
8535a3
Sprite groupGet(Group group, int i)
07b70f
	{ return (Sprite)heliArrayGetValue(&group->sprites, i); }
8535a3
8535a3
int groupOverlap(Group group, Sprite sprite)
8535a3
	{ return groupCollideEx(group, sprite, TRUE, TRUE, 0); }
8535a3
int groupCollide(Group group, Sprite sprite, double bounciness)
8535a3
	{ return groupCollideEx(group, sprite, FALSE, FALSE, bounciness); }
8535a3
int groupBounceOff(Group group, Sprite sprite, double bounciness)
8535a3
	{ return groupCollideEx(group, sprite, FALSE, TRUE, bounciness); }
07b70f
int groupPush(Group group, Sprite sprite, double bounciness)
8535a3
	{ return groupCollideEx(group, sprite, TRUE, FALSE, bounciness); }
8535a3
int groupCollideEx(Group group, Sprite sprite, int keepVelocityGroup, int keepVelocitySprite, double bounciness) {
07b70f
	int result = FALSE;
8535a3
	for(int i = 0; i < groupGetCount(group); ++i)
07b70f
		if (spriteCollideEx(groupGet(group, i), sprite, keepVelocityGroup, keepVelocitySprite, bounciness))
07b70f
			result = TRUE;
07b70f
	return result;
8535a3
}
8535a3
07b70f
int groupOverlapGroup(Group a, Group b)
8535a3
	{ return groupCollideGroupEx(a, b, TRUE, TRUE, 0); }
07b70f
int groupCollideGroup(Group a, Group b, double bounciness)
8535a3
	{ return groupCollideGroupEx(a, b, FALSE, FALSE, bounciness); }
07b70f
int groupBounceOffGroup(Group group, Group other, double bounciness)
07b70f
	{ return groupCollideGroupEx(group, other, FALSE, TRUE, bounciness); }
07b70f
int groupPushGroup(Group group, Group other, double bounciness)
07b70f
	{ return groupCollideGroupEx(group, other, TRUE, FALSE, bounciness); }
8535a3
int groupCollideGroupEx(Group a, Group b, int keepVelocityA, int keepVelocityB, double bounciness) {
07b70f
	int result = FALSE;
8535a3
	for(int i = 0; i < groupGetCount(b); ++i)
07b70f
		if (groupCollideEx(a, groupGet(b, i), keepVelocityA, keepVelocityB, bounciness))
07b70f
			result = TRUE;
07b70f
	return result;
8535a3
}
8535a3
8535a3
double groupGetMinDepth(Group group) {
8535a3
	if (groupGetCount(group) <= 0) return 0;
8535a3
	double md = spriteGetDepth(groupGet(group, 0));
8535a3
	for(int i = 1; i < groupGetCount(group); ++i) {
8535a3
		double d = spriteGetDepth(groupGet(group, i));
8535a3
		if (d < md) md = d;
8535a3
	}
8535a3
	return md;
8535a3
}
8535a3
8535a3
double groupGetMaxDepth(Group group) {
8535a3
	if (groupGetCount(group) <= 0) return 0;
8535a3
	double md = spriteGetDepth(groupGet(group, 0));
8535a3
	for(int i = 1; i < groupGetCount(group); ++i) {
8535a3
		double d = spriteGetDepth(groupGet(group, i));
8535a3
		if (d > md) md = d;
8535a3
	}
8535a3
	return md;
8535a3
}
8535a3
8535a3
07b70f
static void foreachInt(Group group, int value, HeliSpriteEashInt func)
8535a3
	{ for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); }
07b70f
static void foreachDouble(Group group, double value, HeliSpriteEashDouble func)
8535a3
	{ for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); }
07b70f
static void foreachString(Group group, const char *value, HeliSpriteEashString func)
8535a3
	{ for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); }
8535a3
8535a3
8535a3
void groupDestroyTimerEach(Group group, double lifetime)
8535a3
	{ foreachDouble(group, lifetime, &spriteDestroyTimer); }
8535a3
8535a3
void groupSetVisibleEach(Group group, int visible)
8535a3
	{ foreachInt(group, visible, &spriteSetVisible); }
8535a3
void groupSetWidthEach(Group group, double width)
8535a3
	{ foreachDouble(group, width, &spriteSetWidth); }
8535a3
void groupSetHeightEach(Group group, double height)
8535a3
	{ foreachDouble(group, height, &spriteSetHeight); }
8535a3
void groupSetDepthEach(Group group, double depth)
8535a3
	{ foreachDouble(group, depth, &spriteSetDepth); }
8535a3
void groupSetVelocityXEach(Group group, double x)
8535a3
	{ foreachDouble(group, x, &spriteSetVelocityX); }
8535a3
void groupSetVelocityYEach(Group group, double y)
8535a3
	{ foreachDouble(group, y, &spriteSetVelocityY); }
8535a3
void groupSetRotateToDirectionEach(Group group, int rotateToDirection)
8535a3
	{ foreachInt(group, rotateToDirection, &spriteSetRotateToDirection); }
8535a3
void groupSetRotationEach(Group group, double rotation)
8535a3
	{ foreachDouble(group, rotation, &spriteSetRotation); }
8535a3
void groupSetRotationSpeedEach(Group group, double rotationSpeed)
8535a3
	{ foreachDouble(group, rotationSpeed, &spriteSetRotationSpeed); }
8535a3
void groupSetScaleEach(Group group, double scale)
8535a3
	{ foreachDouble(group, scale, &spriteSetScale); }
8535a3
void groupSetMirrorXEach(Group group, int mirrorX)
8535a3
	{ foreachInt(group, mirrorX, &spriteSetMirrorX); }
8535a3
void groupSetMirrorYEach(Group group, int mirrorY)
8535a3
	{ foreachInt(group, mirrorY, &spriteSetMirrorY); }
8535a3
void groupSetAnimationEach(Group group, const char *path)
8535a3
	{ foreachString(group, path, &spriteSetAnimation); }
8535a3
void groupSetShapeColorEach(Group group, const char *color)
8535a3
	{ foreachString(group, color, &spriteSetShapeColor); }
8535a3
void groupSetTintColorEach(Group group, const char *color)
8535a3
	{ foreachString(group, color, &spriteSetTintColor); }
8535a3
8535a3
void groupPointToEach(Group group, double x, double y) {
07b70f
	for(int i = 0; i < groupGetCount(group); ++i)
8535a3
		spritePointTo(groupGet(group, i), x, y);
8535a3
}
8535a3
8535a3
void groupSetSpeedAndDirectionEach(Group group, double speed, double angle) {
07b70f
	for(int i = 0; i < groupGetCount(group); ++i)
8535a3
		spriteSetSpeedAndDirection(groupGet(group, i), speed, angle);
8535a3
}
8535a3
8535a3
void groupSetVelocityEach(Group group, double x, double y) {
07b70f
	for(int i = 0; i < groupGetCount(group); ++i)
8535a3
		spriteSetVelocityXY(groupGet(group, i), x, y);
8535a3
}
8535a3
8535a3
void groupSetColliderEachEx(Group group, Collider type, double xOffset, double yOffset,
8535a3
							double widthOrRadius, double height, double rotationOffset)
8535a3
{
07b70f
	for(int i = 0; i < groupGetCount(group); ++i)
8535a3
		spriteSetColliderEx(groupGet(group, i), type, xOffset, yOffset,
8535a3
							widthOrRadius, height, rotationOffset);
8535a3
}
8535a3
8535a3
void groupSetColliderEach(Group group, Collider type, double xOffset, double yOffset)
8535a3
	{ groupSetColliderEachEx(group, type, xOffset, yOffset, -1, -1, 0); }