bool MGMap::mouseScrollingUpdate(int x, int y) { if(m_MouseScrollingOngoing) { int setY = getScrollY() + m_MouseScrollingYClick - y; int setX = getScrollX() + m_MouseScrollingXClick - x; if(setY > getTopEdge()) { setY = getTopEdge(); } else if(setY < getWindowHeight() - getHeight() * getTileHeight() - getBottomEdge()) { setY = getWindowHeight() - getHeight() * getTileHeight() - getBottomEdge(); } if(setX > getLeftEdge()) { setX = getLeftEdge(); } else if(setX < getWindowWidth() - getWidth() * getTileWidth() - getRightEdge()) { setX = getWindowWidth() - getWidth() * getTileWidth() - getRightEdge(); } setScrollOffset(setX, setY); } return m_MouseScrollingOngoing; }
static void touch(Entity *other) { Entity *e; pushEntity(other); if (other->standingOn == self) { if (self->thinkTime < 5) { playSoundToMap("sound/item/inflate", -1, self->x, self->y, 0); self->health++; } if (self->health == 3) { if (self->thinkTime < 5) { e = addBubble(self->x, self->y, "item/bubble"); e->x = self->face == LEFT ? getLeftEdge(self) : getRightEdge(self); e->x += self->face == LEFT ? -e->w : e->w; e->y = self->y + self->h / 2 - e->h / 2; e->dirX = self->face == LEFT ? -e->speed : e->speed; } self->thinkTime = 60; } else if (self->health > 3) { self->health = 3; self->thinkTime = 60; } else { self->thinkTime = 10; } setEntityAnimationByID(self, self->health + 3); } }
int MGMap::getTileIndex(int clickX, int clickY) { MGFLOG_INFO("MGMap::getTileIndex(" << clickX << ", " << clickY << ")"); if( clickX > getLeftEdge() && clickX < (getWindowWidth() - getRightEdge()) && clickY > getTopEdge() && clickY < (getWindowHeight() - getBottomEdge())) { int x = (clickX - getScrollX()) / getTileWidth(); int y = (clickY - getScrollY()) / getTileHeight(); if(x < getWidth() && y < getHeight()) { return y * getWidth() + x; } } return -1; // Click outside of map }
void addToGrid(Entity *e) { int left, right, top, bottom, x, y; if (e == &playerWeapon) { if (e->face == LEFT) { left = (e->x - e->w + e->offsetX - 1) / TILE_SIZE / GRID_SIZE; right = (e->x + e->offsetX - 1) / TILE_SIZE / GRID_SIZE; } else { left = (e->x + e->offsetX) / TILE_SIZE / GRID_SIZE; right = (e->x + e->offsetX + e->w) / TILE_SIZE / GRID_SIZE; } top = e->y / TILE_SIZE / GRID_SIZE; bottom = (e->y + e->h) / TILE_SIZE / GRID_SIZE; } else { left = getLeftEdge(e) / TILE_SIZE / GRID_SIZE; right = getRightEdge(e) / TILE_SIZE / GRID_SIZE; top = (e->y + e->box.y) / TILE_SIZE / GRID_SIZE; bottom = (e->y + e->box.y + e->box.h) / TILE_SIZE / GRID_SIZE; } for (x=left;x<=right;x++) { for (y=top;y<=bottom;y++) { addToList(y, x, e); } } }
Entity *checkEntityToEntity(Entity *e) { int i, j, x1, y1, x2, y2, w1, h1, w2, h2; Entity *e1, *e2; EntityList *list1, *list2; for (i=0;i<GRID_MAX_Y;i++) { for (j=0;j<GRID_MAX_X;j++) { for (list1=grid[i][j].listHead.next;list1!=NULL;list1=list1->next) { e1 = list1->entity; if (e1 != e) { continue; } if (e1->inUse == TRUE) { for (list2=grid[i][j].listHead.next;list2!=NULL;list2=list2->next) { e2 = list2->entity; if (e1 != e2 && e2->inUse == TRUE && e2->touch != NULL && e2->weight > 0) { if (e1->type == ENEMY && e2->type == ENEMY) { continue; } if (e1->type == ANTI_GRAVITY || e2->type == ANTI_GRAVITY) { continue; } if ((e1->type != PLAYER && (e2->flags & PLAYER_TOUCH_ONLY)) || ((e1->flags & PLAYER_TOUCH_ONLY) && e2->type != PLAYER)) { continue; } if (e1->type == PROJECTILE) { if (e2->type == PROJECTILE || (e1->parent != NULL && e1->parent->type == ENEMY && e2->type == ENEMY)) { continue; } } if ((e1 == &player && e2 == &playerWeapon) || (e1 == &playerWeapon && e2 == &player)) { continue; } x1 = getLeftEdge(e1); y1 = e1->y + e1->box.y; w1 = e1->box.w; h1 = e1->box.h; x2 = getLeftEdge(e2); y2 = e2->y + e2->box.y; w2 = e2->box.w; h2 = e2->box.h; if (e1 == &playerWeapon) { x1 = e1->x + e1->box.x; y1 = e1->y + e1->box.y; if (e1->face == LEFT) { x1 += e1->parent->w - e1->w - e1->offsetX; } else { x1 += e1->offsetX; } y1 += e1->offsetY; } if (collision(x1, y1, w1, h1, x2, y2, w2, h2) == TRUE) { return e2; } } } } } } } return NULL; }
void doCollisions() { int i, j, x1, y1, x2, y2, w1, h1, w2, h2; Entity *e1, *e2, *temp; EntityList *list1, *list2; for (i=0;i<GRID_MAX_Y;i++) { for (j=0;j<GRID_MAX_X;j++) { for (list1=grid[i][j].listHead.next;list1!=NULL;list1=list1->next) { e1 = list1->entity; if (e1->flags & TELEPORTING) { continue; } if (e1->inUse == TRUE && e1->touch != NULL) { for (list2=grid[i][j].listHead.next;list2!=NULL;list2=list2->next) { e2 = list2->entity; if ((e1->type != PLAYER && (e2->flags & PLAYER_TOUCH_ONLY)) || ((e1->flags & PLAYER_TOUCH_ONLY) && e2->type != PLAYER)) { continue; } if ((e1->type == CONVEYOR_BELT && e2->type == CONVEYOR_BELT) || (e1->type == WEAK_WALL && e2->type == WEAK_WALL) || (e1->type == ANTI_GRAVITY && e2->type == ANTI_GRAVITY)) { continue; } if (e2->flags & TELEPORTING) { continue; } if (e1 != e2 && e2->inUse == TRUE && e2->touch != NULL) { if (e1->type == PROJECTILE) { if (e2->type == PROJECTILE || (e1->parent != NULL && (e1->parent->type == ENEMY || e1->parent->type == SPAWNER) && e2->type == ENEMY)) { continue; } } if ((e1 == &player && e2 == &playerWeapon) || (e1 == &playerWeapon && e2 == &player)) { continue; } x1 = getLeftEdge(e1); y1 = e1->y + e1->box.y; w1 = e1->box.w; h1 = e1->box.h; x2 = getLeftEdge(e2); y2 = e2->y + e2->box.y; w2 = e2->box.w; h2 = e2->box.h; if (e1 == &playerWeapon) { if (e1->face == LEFT) { x1 = e1->parent->x - e1->w + e1->offsetX - 1; } else { x1 = e1->x + e1->offsetX; } y1 = e1->parent->y + e1->offsetY; } else if (e2 == &playerWeapon) { if (e2->face == LEFT) { x2 = e2->parent->x - e2->w + e2->offsetX - 1; } else { x2 = e2->x + e2->offsetX; } y2 = e2->parent->y + e2->offsetY; } if (collision(x1, y1, w1, h1, x2, y2, w2, h2) == TRUE) { temp = self; self = e2; self->touch(e1); self = temp; } } if (e1->inUse == FALSE) { break; } } } } } } }
void pushEntity(Entity *other) { int pushable, collided; int x1, x2, y1, y2; Entity *temp; float dirX; static int depth = 0; long wasOnGround; if (other->touch == NULL || (other->type == WEAPON && (other->flags & ATTACKING)) || (other->flags & PLAYER_TOUCH_ONLY)) { return; } if (other->flags & OBSTACLE) { return; } if (other->type == PROJECTILE) { temp = self; self = other; self->die(); self = temp; return; } other->x -= other->dirX; other->y -= other->dirY; /* if (other->type == PLAYER && other->dirX > 0) { other->x = ceil(other->x); } else if (other->type == PLAYER && other->dirX < 0) { other->x = floor(other->x); } */ x1 = getLeftEdge(self); y1 = self->y + self->box.y; x2 = getLeftEdge(other); y2 = other->y + other->box.y; pushable = (self->flags & PUSHABLE); if ((self->flags & OBSTACLE) || depth == 1) { pushable = 0; } collided = FALSE; /* Test the vertical movement */ if (other->dirY > 0) { /* Trying to move down */ if (collision(x1, y1, self->box.w, self->box.h, x2, y2 + ceil(other->dirY), other->box.w, other->box.h) == TRUE) { if (self->dirY < 0) { other->y -= self->dirY; other->dirY = self->dirY; dirX = other->dirX; other->dirX = 0; checkToMap(other); if (other->dirY == 0) { self->y = other->y + other->h; self->dirY = 0; } other->dirX = dirX; } if (self->type != AUTO_DOOR || (self->type == AUTO_DOOR && (int)self->startY == (int)self->endY)) { /* Place the entity as close as possible */ other->y = self->y + self->box.y; other->y -= other->box.h + other->box.y; other->standingOn = self; other->dirY = 0; other->flags |= ON_GROUND; collided = TRUE; } else { self->y = other->y - other->h; } } } else if (other->dirY < 0 && !(self->flags & ON_GROUND)) { /* Trying to move up */ if (collision(x1, y1, self->box.w, self->box.h, x2, y2 + floor(other->dirY), other->box.w, other->box.h) == TRUE) { /* Place the entity as close as possible */ other->y = self->y + self->box.y; other->y += self->box.h; other->dirY = 0; collided = TRUE; } } else if (self->type == AUTO_DOOR && other->dirY == 0 && self->dirY > 0) { if (collision(x1, y1, self->box.w, self->box.h, x2, y2 + floor(other->dirY), other->box.w, other->box.h) == TRUE) { self->y = other->y - self->h; collided = TRUE; } } /* Test the horizontal movement */ if (other->dirX > 0 && collided == FALSE) { /* Trying to move right */ if (collision(x1, y1, self->box.w, self->box.h, x2 + ceil(other->dirX), y2, other->box.w, other->box.h) == TRUE) { if (pushable != 0) { self->y -= self->dirY; /*self->dirX += ceil(other->dirX);*/ self->dirX += other->dirX; wasOnGround = (self->flags & ON_GROUND); checkToMap(self); if (wasOnGround != 0) { self->flags |= ON_GROUND; } self->y -= self->dirY; depth++; if (checkEntityToEntity(self) != NULL) { self->x -= other->dirX; self->dirX = 0; } depth--; if (self->dirX == 0) { pushable = 0; } else { self->frameSpeed = 1; } self->y += self->dirY; } if (pushable == 0) { /* Place the entity as close as possible */ other->x = getLeftEdge(self) - other->w; if (other->face == RIGHT) { other->x += other->w - other->box.x - other->box.w; } else { other->x += other->w - other->box.w; } other->dirX = (other->flags & BOUNCES) ? -other->dirX : 0; if ((other->flags & GRABBING) && other->target != NULL) { other->target->x -= other->target->dirX; other->target->dirX = 0; } } if ((other->flags & GRABBING) && other->target == NULL && (self->flags & PUSHABLE)) { other->target = self; self->flags |= GRABBED; } collided = TRUE; } } else if (other->dirX < 0 && collided == FALSE) { /* Trying to move left */ if (collision(x1, y1, self->box.w, self->box.h, x2 + floor(other->dirX), y2, other->box.w, other->box.h) == TRUE) { if (pushable != 0) { self->y -= self->dirY; /*self->dirX += floor(other->dirX);*/ self->dirX += other->dirX; wasOnGround = (self->flags & ON_GROUND); checkToMap(self); if (wasOnGround != 0) { self->flags |= ON_GROUND; } self->y -= self->dirY; depth++; if (checkEntityToEntity(self) != NULL) { self->x -= other->dirX; self->dirX = 0; } depth--; if (self->dirX == 0) { pushable = 0; } else { self->frameSpeed = -1; } self->y += self->dirY; } if (pushable == 0) { /* Place the entity as close as possible */ other->x = getRightEdge(self); if (other->face == RIGHT) { other->x -= other->box.x; } else { other->x -= other->w - (other->box.w + other->box.x); } other->dirX = (other->flags & BOUNCES) ? -other->dirX : 0; if ((other->flags & GRABBING) && other->target != NULL) { other->target->x -= other->target->dirX; other->target->dirX = 0; } } if ((other->flags & GRABBING) && other->target == NULL && (self->flags & PUSHABLE)) { other->target = self; self->flags |= GRABBED; } collided = TRUE; } } other->x += other->dirX; other->y += other->dirY; }