static void plasmaAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { playSoundToMap("sound/boss/snake_boss/snake_boss_shot", BOSS_CHANNEL, self->x, self->y, 0); if (self->mental == 1) { e = addProjectile("boss/snake_boss_special_shot", self, 0, 0, 0, 0); e->takeDamage = &plasmaTakeDamage; } else { e = addProjectile("boss/snake_boss_normal_shot", self, 0, 0, 0, 0); } e->flags |= FLY|UNBLOCKABLE; e->x = self->x + self->w / 2 - e->w / 2; e->y = self->y + self->h / 2 - e->h / 2; e->targetX = player.x + player.w / 2 - e->w / 2; e->targetY = player.y + player.h / 2 - e->h / 2; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->dirX *= 12; e->dirY *= 12; self->mental--; if (self->mental <= 0) { self->thinkTime = 120; self->action = &plasmaAttackFinish; } else { self->thinkTime = 30; } } hover(); }
static void explode() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { for (i=0;i<360;i+=12) { e = addProjectile("weapon/spike", &player, 0, 0, 0, 0); e->x = self->x + self->w / 2 - e->w / 2; e->y = self->y + self->h / 2 - e->h / 2; e->dirX = (0 * cos(DEG_TO_RAD(i)) - 12 * sin(DEG_TO_RAD(i))); e->dirY = (0 * sin(DEG_TO_RAD(i)) + 12 * cos(DEG_TO_RAD(i))); e->face = e->dirX < 0 ? LEFT : RIGHT; e->flags |= FLY|ATTACKING; e->reactToBlock = &bounceOffShield; } self->inUse = FALSE; } checkToMap(self); }
static void fireBullets() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->maxThinkTime--; playSoundToMap("sound/boss/fly_boss/fly_boss_bullet", -1, self->x, self->y, 0); e = addProjectile("boss/fly_boss_shot", self, self->x + (self->face == RIGHT ? self->w : 0), self->y + self->h / 2, (self->face == RIGHT ? 7 : -7), 0); e->dirY = 0.1 * (prand() % 2 == 0 ? -1 : 1); e->reactToBlock = &bounceOffShield; if (self->maxThinkTime <= 0) { self->thinkTime = 120; self->action = &attackFinished; } else { self->thinkTime = 6; } } }
static void fireSlime() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->maxThinkTime--; playSoundToMap("sound/boss/grub_boss/fire", -1, self->x, self->y, 0); e = addProjectile("boss/fly_boss_slime", self, self->x + (self->face == RIGHT ? self->w : 0), self->y + self->h / 2, (self->face == RIGHT ? 7 : -7), 0); e->touch = &slimePlayer; if (self->maxThinkTime <= 0) { self->thinkTime = 60; self->action = ((player.flags & HELPLESS) || prand() % 3 == 0) ? &bulletFireMoveToPosition : &attackFinished; } else { self->thinkTime = 30; } } }
static void breatheFireInit() { Entity *e; setEntityAnimation(self, "ATTACK_1"); e = addProjectile("enemy/fireball", self, 0, 0, (self->face == LEFT ? -6 : 6), 0); if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; e->flags |= FLY; playSoundToMap("sound/enemy/fireball/fireball", -1, self->x, self->y, 0); self->thinkTime = 30; self->action = &breatheFireWait; checkToMap(self); }
static void entityWait() { int x, y; Entity *e; if (prand() % 60 == 0) { x = self->x + self->w / 2 + ((prand() % 6) * (prand() % 2 == 0 ? -1 : 1)); y = self->y + self->h - prand() % 10; e = addProjectile("enemy/slime_drip", self, x, y, 0, 0); e->x -= e->w / 2; e->touch = NULL; } x = self->x - 16; if (player.health > 0 && collision(x, self->y, self->w + 32, self->endY, player.x, player.y, player.w, player.h) == 1) { self->action = &bite; self->touch = &trapEntity; setEntityAnimation(self, "WALK"); self->flags &= ~FLY; self->dirY = self->speed; } }
static void shotAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { playSoundToMap("sound/boss/snake_boss/snake_boss_shot", BOSS_CHANNEL, self->x, self->y, 0); if (prand() % 4 == 0 && self->startX == 0) { e = addProjectile("boss/snake_boss_special_shot", self, self->x + self->w / 2, self->y + self->h / 2, (self->face == RIGHT ? 7 : -7), 0); e->action = &specialShotMove; e->reactToBlock = &specialShotBlock; self->startX = 1; } else { e = addProjectile("boss/snake_boss_normal_shot", self, self->x + self->w / 2, self->y + self->h / 2, (self->face == RIGHT ? 7 : -7), 0); e->reactToBlock = &bounceOffShield; } e->y -= e->h / 2; self->x += (self->face == LEFT ? 10 : -10); self->maxThinkTime--; if (self->maxThinkTime <= 0) { self->action = &attackFinished; } else { self->thinkTime = 10; } } alignBodyToHead(); }
static void spitIce() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { facePlayer(); e = addProjectile("enemy/ice", self, self->x, self->y, 0, 0); if (e == NULL) { showErrorAndExit("No free slots to add Ice"); } e->face = self->face; e->flags |= PLAYER_TOUCH_ONLY|FLY; if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; calculatePath(e->x, e->y, player.x + player.w / 2, player.y + player.h / 2, &e->dirX, &e->dirY); e->dirX *= 8; e->dirY *= 8; e->touch = &iceTouch; self->mental--; if (self->mental <= 0) { setEntityAnimation(self, "ICE_STAND"); self->thinkTime = 60; self->action = &spitFinish; } else { self->thinkTime = 30; } } checkToMap(self); }
static void phantasmalBolt() { Entity *e; if (self->mental == 0) { setEntityAnimation(self, "PHANTASMAL_BOLT_FIRE"); e = addProjectile("boss/azriel_phantasmal_bolt", self, self->x, self->y, self->face == LEFT ? -8 : 8, 0); e->face = self->face; e->damage = player.health / 2; if (e->damage == 0) { e->damage = 1; } setEntityAnimation(e, "FIRE"); playSoundToMap("sound/boss/snake_boss/snake_boss_shot", -1, self->x, self->y, 0); if (self->face == LEFT) { e->x = self->x + self->w - e->w - e->offsetX; } else { e->x = self->x + e->offsetX; } e->y = self->y + e->offsetY; e->action = &phantasmalBoltMove; e->flags |= FLY; e->reactToBlock = &phantasmalBoltReflect; e->thinkTime = 1200; e->mental = 2; self->thinkTime = 120; self->action = &phantasmalBoltFinish; self->endY = 0; self->head->mental = 1; } checkToMap(self); becomeTransparent(); }
static void spit() { Entity *e; int x, y; x = self->x + self->w / 2; y = self->y + 5; e = addProjectile("common/green_blob", self, x, y, -6, 0); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self, x, y, -6, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self, x, y, 0, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self, x, y, 6, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self, x, y, 6, 0); e->flags |= FLY; e->reactToBlock = &bounceOffShield; playSoundToMap("sound/common/pop", -1, self->x, self->y, 0); setEntityAnimation(self, "ATTACK_2"); self->animationCallback = &spitFinish; }
static void webAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->thinkTime = 60; e = addProjectile("misc/web", self, self->x, self->y + self->h / 2, (self->face == LEFT ? -8 : 8), 0); switch (self->mental) { case 3: e->dirY = -0.1; break; case 2: e->dirY = 0.1; break; default: e->dirY = 0; break; } e->x += self->face == LEFT ? -e->w : self->w; e->y -= e->h / 2; e->flags |= FLY; e->draw = &drawLoopingAnimationToMap; e->touch = &webTouch; e->reactToBlock = &bounceOffShield; e->face = self->face; setEntityAnimation(e, "STAND"); self->mental--; self->thinkTime = 15; self->action = self->mental == 0 ? &webAttackFinished : &webAttack; } checkToMap(self); }
static void flameTouch(Entity *other) { Entity *e; if (other->type == PLAYER && self->startX == 0) { e = addProjectile("enemy/fireball", self->head, 0, 0, (self->face == LEFT ? -8 : 8), 0); e->x = other->x + other->w / 2 - e->w / 2; e->y = other->y + other->h / 2 - e->h / 2; e->flags |= FLY|NO_DRAW; self->startX = 7; } }
static void skullAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimation(self, "ATTACK"); e = addProjectile("enemy/skull_shot", self, self->x, self->y, self->face == LEFT ? -6 : 6, 0); playSoundToMap("sound/boss/snake_boss/snake_boss_shot", -1, self->x, self->y, 0); if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; e->face = self->face; e->action = &skullShotMove; e->flags |= FLY; e->reactToBlock = &skullShotReflect; e->thinkTime = 1200; e->mental = 2; self->thinkTime = 60; self->action = &skullAttackFinish; } checkToMap(self); }
static void spitAttack() { int x, y; Entity *e; x = self->x + (self->face == LEFT ? -5 : self->w - 6); y = self->y + 21; e = addProjectile("common/green_blob", self, x, y, (self->face == LEFT ? -6 : 6), 0); e->y -= e->h / 2; e->flags |= FLY; e->reactToBlock = &bounceOffShield; setEntityAnimation(self, "ATTACK_2"); self->animationCallback = &spitAttackFinish; }
static void finalAttack() { Entity *e; if (self->endY == 1) { self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimation(self, "GROUND_ATTACK"); e = addProjectile("boss/fly_boss_slime", self, self->x + (self->face == RIGHT ? self->w : 0), self->y, (self->face == RIGHT ? 7 : -7), 0); e->touch = &slimePlayer; self->endY = 0; self->die = &dieWait; } } }
static void specialShotTouch(Entity *other) { Entity *e; if (other->type == WEAPON && (other->flags & ATTACKING)) { e = addProjectile("boss/snake_boss_special_shot", &player, self->x, self->y, 0, 0); e->targetX = self->target->x + self->target->w / 2; e->targetY = self->target->y + self->target->h / 2; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->dirX *= 12; e->dirY *= 12; e->dirX = (player.face == RIGHT ? fabs(e->dirX) : fabs(e->dirX) * -1); e->damage = 10; self->inUse = FALSE; } }
static void flameWait() { Entity *e; self->health--; player.flags &= ~FLY; if (self->health % 10 == 0) { if (collision(player.x, player.y, player.w, player.h, self->x, self->y, self->w, self->h) == 1) { e = addProjectile("enemy/fireball", self->head, 0, 0, (self->face == LEFT ? -self->dirX : self->dirX), 0); e->touch = &flameTouch; e->element = DRAGON_FIRE; e->damage = 100; e->x = player.x + player.w / 2 - e->w / 2; e->y = player.y + player.h / 2 - e->h / 2; e->flags |= FLY|NO_DRAW; } } self->thinkTime--; if (self->thinkTime <= 0 || self->head->health <= 0) { self->head->mental = 0; self->inUse = FALSE; } }
void ServerWorldModel::handlePlayerShooting(PlayerId playerId, ServerPlayers &players) { int currentTick = getTimeHandler()->getTick(); Tickf currentTickf = static_cast<Tickf>(currentTick); PlayerObj *playerObj = getPlayerObjs()[playerId]; // Copy userCmd, we must have a seperate copy to alter while original is intact. UserCmd userCmd(playerObj->getUserCmd()); ClientIdGenerator *clientIdGenerator = players[playerId]->getIdGenerator(); int clientNShots = userCmd.nShots; assert(userCmd.firstShotTick >= currentTickf); assert(playerObj->getNextShootTick() >= currentTickf); // remove projectiles if client created projectiles which we did't notice before while (userCmd.firstProjectileId > clientIdGenerator->getNextId()) { RemoveProjectile removeProjectile(clientIdGenerator->generateGameObjId()); players[playerId]->link.pushMessage(removeProjectile, getTimeHandler()->getTime(), getTimeHandler()->getTick()); } assert(userCmd.firstProjectileId == clientIdGenerator->getNextId()); if (clientNShots > 0) { assert(userCmd.firstShotTick >= playerObj->getNextShootTick()); // Do any shooting int serverNShots = 0; Tickf shotTick; Projectile::Type weapon = userCmd.weapon; for(int i=0; i<clientNShots; ++i) { GameObjId projectileId = clientIdGenerator->generateGameObjId(); if (playerTryShoot(playerId, currentTick, i, projectileId, shotTick)) { if (serverNShots == 0) userCmd.firstShotTick = shotTick; Projectile *projectile = (getProjectiles())[projectileId]; std::cout << "server tick: " << getTimeHandler()->getTick() << " projectile shot, objLag = " << projectile->getObjLag() << std::endl; // send projectile to all clients AddProjectile addProjectile(projectileId, projectile->getType(), projectile->getPos(), projectile->getAngle().getFloat(), projectile->getShooterId(), projectile->getShootTick(), projectile->getObjLag()); pushMessageToAll(players, addProjectile, getTimeHandler()->getTime(), getTimeHandler()->getTick()); ++serverNShots; } else { RemoveProjectile removeProjectile(projectileId); players[playerId]->link.pushMessage(removeProjectile, getTimeHandler()->getTime(), getTimeHandler()->getTick()); } } userCmd.nShots = serverNShots; // Safe to overwrite PlayerObj.userCmd now, write changes playerObj->setUserCmd(&userCmd); } }
static void superFireballAttack() { int i; Entity *e; checkToMap(self); if (self->endY == 1 && (self->flags & ON_GROUND)) { setEntityAnimation(self, "ATTACK_1"); if (self->thinkTime == -1) { for (i=0; i<6; i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add the Fireball Attack particle"); } loadProperties("boss/awesome_fireball_particle", e); setEntityAnimation(e, "STAND"); e->head = self; if (self->face == LEFT) { e->x = self->x + self->w - e->w - e->offsetX; } else { e->x = self->x + e->offsetX; } e->y = self->y + self->offsetY; e->startX = e->x; e->startY = e->y; e->draw = &drawLoopingAnimationToMap; e->mental = 360; e->health = i * 60; e->action = &fireballChargeWait; } self->mental = 6; self->thinkTime = 0; } else if (self->mental <= 0) { self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimation(self, "ATTACK_2"); for (i=0; i<5; i++) { e = addProjectile("boss/awesome_super_fireball", self, self->x, self->y, (self->face == RIGHT ? 14 : -14), 0); e->touch = &fireballTouch; e->action = &fireballMove; e->type = ENEMY; e->x += (self->face == RIGHT ? self->w : e->w); e->y += self->offsetY; e->x += self->face == RIGHT ? -2 : 2; } playSoundToMap("sound/boss/awesome_boss/hadouken", BOSS_CHANNEL, self->x, self->y, 0); self->thinkTime = 120; self->target->thinkTime = 120; self->action = &superFireballAttackFinished; self->target->action = &superFireballAttackFinished; } } } else if (self->endY == 0 && self->target->health <= 0) { self->thinkTime = 120; self->action = &teleportOut; } }
static void podExplode() { int x, y; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = addProjectile("common/green_blob", self->head, 0, 0, -6, 0); x = self->x + self->w / 2 - e->w / 2; y = self->y; e->x = x; e->y = y; e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, -6, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, 0, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, 6, -6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, -6, 6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, 0, 6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, 6, 6); e->flags |= FLY; e->reactToBlock = &bounceOffShield; e = addProjectile("common/green_blob", self->head, x, y, 6, 0); e->flags |= FLY; e->reactToBlock = &bounceOffShield; playSoundToMap("sound/common/pop", -1, self->x, self->y, 0); self->inUse = FALSE; } checkToMap(self); }
void ProjectileManager::createLaser(Ogre::Vector3 startPosition, Ogre::Vector3 speed) { int damage(100); std::shared_ptr<Laser> laser(new Laser(mSceneMgr, startPosition, damage, speed, mProjectilesList.size())); addProjectile(laser); }
static void spitAcid() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { for (i=0;i<3;i++) { e = addProjectile("boss/cave_boss_acid", self, self->x, self->y, (self->face == RIGHT ? 2 : -2), 0); if (e == NULL) { showErrorAndExit("No free slots to add Acid"); } e->damage = 1; e->face = self->face; e->flags |= PLAYER_TOUCH_ONLY|FLY; if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; if (i != 0) { e->dirY = i == 1 ? -0.5 : 0.5; } e->dirX *= 3; e->dirY *= 3; } self->mental--; if (self->mental <= 0) { setEntityAnimation(self, "NORMAL_STAND"); self->thinkTime = 60; self->action = &spitFinish; } else { self->thinkTime = 30; } } checkToMap(self); }
static void spitFire() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { for (i=0;i<self->endY;i++) { e = addProjectile("enemy/fireball", self, self->x, self->y, (self->face == RIGHT ? 2 : -2), 0); if (e == NULL) { showErrorAndExit("No free slots to add a Fireball"); } playSoundToMap("sound/enemy/fireball/fireball", BOSS_CHANNEL, self->x, self->y, 0); e->damage = 1; e->face = self->face; e->flags |= PLAYER_TOUCH_ONLY; if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; if (self->endY == 3) { if (i != 0) { e->dirY = i == 1 ? -0.5 : 0.5; } } else { if (i == 0) { e->dirY = 0; } else if (i < 3) { e->dirY = i == 1 ? -0.5 : 0.5; } else { e->dirY = i == 3 ? -1 : 1; } } e->dirX *= 3; e->dirY *= 3; } self->mental--; if (self->mental <= 0) { setEntityAnimation(self, "FIRE_STAND"); self->thinkTime = 60; self->action = &spitFinish; } else { self->thinkTime = 30; } } checkToMap(self); }