void enemy::manhackAI(float elapsed) { flying = false; manhackTargetAcquire(); if (!weaponMelee() && attacking() && bowDrawn()) endAttack(); if (target != NULL) { startAttack(); flying = true; float myX = getX() + getMaskWidth() / 2; float theirX = target->getX() + target->getMaskWidth() / 2; if (theirX > myX) facingX = 1; else facingX = -1; //find the desired position float desiredX = target->getX() + target->getMaskWidth() / 2; float desiredY = target->getY() + target->getMaskHeight() / 2; desiredX += orbitRange * cos(angle); desiredY += orbitRange * sin(angle); if (timer >= 0) //orbit the desired position angle += elapsed * orbitSpeed; if (weaponMelee()) { //handle the timer float oldT = timer; timer += elapsed * ORBITTIMERSPEED; if (oldT < 0 && timer >= 0) manhackAIOrbitDetails(); //move back out again else if (timer >= 1 && getY() <= target->getY()) { //move in for the strike! timer = orbitRange * -ORBITTIMERSPEED / moveSpeed(); orbitRange = 0; } } //move in that direction float xDif = desiredX - x; float yDif = desiredY - y; float dis = sqrt(xDif * xDif + yDif * yDif); if (dis <= moveSpeed() * elapsed) { x = desiredX; y = desiredY; } else flyMove(xDif / dis, yDif / dis, elapsed); } }
void enemy::copterAI(float elapsed) { manhackTargetAcquire(); flying = false; if (attacking() && bowDrawn()) endAttack(); if (target != NULL) { flying = true; float myX = getX() + getMaskWidth() / 2; float theirX = target->getX() + target->getMaskWidth() / 2; float myY = getY() + getMaskHeight() / 2; float theirY = target->getY() + target->getMaskHeight() / 2; float xDif = abs(myX - theirX); float yDif = abs(myY - theirY); if (myX > theirX) facingX = -1; else facingX = 1; float xMove = 0; float yMove = 0; if (xDif > maxRange) { if (myX > theirX) xMove = -1; else xMove = 1; } else if (xDif < maxRange / 2) { if (myX > theirX) xMove = COPTERBACKOFF; else xMove = -COPTERBACKOFF; } if (yDif > moveSpeed() * elapsed) { if (myY > theirY) yMove = -1; else yMove = 1; } if (yDif < CLOSERANGE) startAttack(); if (xMove != 0 || yMove != 0) { float dif = sqrt(xMove * xMove + yMove * yMove); flyMove(xMove / dif, yMove / dif, elapsed); } } }
void Curupira::update(SDL_Rect target) { //loop("[Curupira] Updating."); updatePosition(target); switch (m_state) { case UNDERGROUND: underground(); break; case STANDING: standing(); break; case ATTACKING: attacking(); break; case MOVING: moving(); break; } if(!m_hunt || !m_rose) { m_state = UNDERGROUND; } else if (m_damaging) { m_state = ATTACKING; } else { m_state = MOVING; if(isOnLeftDirection()) { //condition("[Curupira] Moving Backward."); m_looking = BACKWARD; } else if(isOnRightDirection()) { //condition("[Curupira] Moving Forward."); m_looking = FORWARD; } } }
void enemy::archerAI(float elapsed) { //archer AI dropMode = false; if (target == NULL) target = inRange(ACQUIRERANGE); forceTarget(); if (timer > 0) timer -= elapsed; if (attacking() && !weaponMelee() && bowDrawn()) endAttack(); //properly finish your ranged attack, even if they get out of the way if (target != NULL) { //switch target if necessary creature *iR = inRange(ACQUIRERANGE); if (iR != NULL) target = iR; float myX = getX() + getMaskWidth() / 2; float theirX = target->getX() + target->getMaskWidth() / 2; if (abs(theirX - myX) > maxRange) { //get into range if (theirX > myX) move(1, elapsed); else move(-1, elapsed); } else if (abs(target->getY() + target->getMaskHeight() / 2 - getY() - getMaskHeight() / 2) < CLOSERANGE && !attacking()) { if (theirX > myX) facingX = 1; else facingX = -1; if (abs(theirX - myX) <= weaponReach() + getMaskWidth() / 2 - 1) { //switch to a melee weapon and attack them if (!weaponMelee()) switchWeapon(); startAttack(); } else if (abs(theirX - myX) < MEDIUMRANGE) { //charge them if (theirX > myX) move(1, elapsed); else move(-1, elapsed); } else { if (magic != DATA_NONE) { if (timer <= 0) { global_map->magic(this, magic, TYPE_PLAYER); //use your magic timer = ARCHERFREQUENCY; } } else { //switch to a ranged weapon, and shoot it if (weaponMelee()) switchWeapon(); startAttack(); } } } else if (canJump && target->grounded()) { if (target->getY() > y + CLOSERANGE) dropMode = true; else if (target->getY() < y - CLOSERANGE) jump(BIGJUMP); } } }
void enemy::wprinAI(float elapsed) { unsigned int totalBossResource = (unsigned int) ((1 - healthFraction()) / (global_data->getValue(DATA_BOSSDATA, magic, 8) * 0.01f)); if (bossPhase < 10 && healthFraction() < 1) { global_map->forceDialogue(global_data->getValue(DATA_BOSSDATA, magic, 0) + 10); bossPhase = 10; global_map->forceMusic(BOSSMUSIC); } switch(bossPhase) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: if (!global_map->dialogueActive()) { global_map->forceDialogue(global_data->getValue(DATA_BOSSDATA, magic, 0) + bossPhase); bossPhase += 1; if (bossPhase == 10) global_map->forceMusic(BOSSMUSIC); } break; case 10: //combat start if (!global_map->dialogueActive()) { { //pick a position BESIDES the one you are at already unsigned int pPick = rand() % 2; switch(bossProb) { case 0: bossProb = 1 + pPick; break; case 1: if (pPick == 0) bossProb = 0; else bossProb = 2; break; case 2: bossProb = pPick; break; } } //teleport to that position global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 7), TYPE_PLAYER); x = 1.0f * global_data->getValue(DATA_BOSSDATA, magic, bossProb * 2 + 1) - getMaskWidth() / 2; y = global_map->getHeight() - (global_data->getValue(DATA_BOSSDATA, magic, bossProb * 2 + 2) - getMaskHeight()) - (1 + GENERATOR_BOTTOMBORDER) * TILESIZE; //reset timer bossTimer = 0; //pick an attack pattern based on the position switch(bossProb) { case 0: case 1: flying = false; if (bossProb == 0) facingX = 1; else facingX = -1; if (rand() % 2 == 0) bossPhase = 11; else bossPhase = 14; break; case 2: flying = true; if (rand() % 2 == 0) bossPhase = 13; else bossPhase = 15; break; } if ((unsigned int) bossResource < totalBossResource) { //summon a monster instead of what you picked bossPhase = 12; bossResource += 1; } } break; case 11: //attack { if (bossTimer > 0 && !attacking()) bossPhase = 10; //teleport again else { startAttack(); bossTimer += elapsed; } } break; case 12: //summon { float bTOld = bossTimer; bossTimer += elapsed; float sPoint = global_data->getValue(DATA_BOSSDATA, magic, 9) * 0.01f; if (bossTimer >= sPoint && bTOld < sPoint) { //summon unsigned int sXA = 0; creature *sP = sampleP(); if (sP->getX() + sP->getMaskWidth() / 2 < global_map->getWidth() / 2) sXA += 1; float sX = global_data->getValue(DATA_BOSSDATA, magic, 11 + sXA) * 1.0f; float sY = global_map->getHeight() - (1 + GENERATOR_BOTTOMBORDER) * TILESIZE; unsigned int sTypeA = 0; if (bossResource > global_data->getValue(DATA_BOSSDATA, magic, 13)) sTypeA += 1; global_map->summon(sX, sY, global_data->getValue(DATA_BOSSDATA, magic, 14 + sTypeA), true, true); //it's a boss so it doesn't give EXP } else if (bossTimer > global_data->getValue(DATA_BOSSDATA, magic, 10) * 0.01f) bossPhase = 10; //teleport } break; case 13: //poison rain { if (bossTimer == 0) global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 16), TYPE_PLAYER); bossTimer += elapsed; if (bossTimer >= global_data->getValue(DATA_BOSSDATA, magic, 17) * 0.01f) bossPhase = 10; //use teleport again } break; case 14: //moon burst { if (bossTimer == 0) global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 18), TYPE_PLAYER); bossTimer += elapsed; if (bossTimer >= global_data->getValue(DATA_BOSSDATA, magic, 19) * 0.01f) bossPhase = 10; //use teleport again } break; case 15: //moon blast { float oldBT = bossTimer; bossTimer += elapsed; float dropInterval = global_data->getValue(DATA_BOSSDATA, magic, 23) * 0.01f; unsigned int dropR = (unsigned int) (bossTimer / dropInterval); while (oldBT <= dropR * dropInterval && oldBT <= global_data->getValue(DATA_BOSSDATA, magic, 24) * 0.01f) { //use a spell float angle = (rand() % 100) * 0.01f * (float) M_PI; global_map->addProjectile(getX() + getMaskWidth() / 2, getY() + getMaskHeight() / 2, cos(angle), sin(angle), global_data->getValue(DATA_BOSSDATA, magic, 21), global_data->getValue(DATA_BOSSDATA, magic, 22), DATA_NONE, TYPE_ENEMY, DATA_NONE, false); global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 20), TYPE_PLAYER); oldBT += dropInterval; } if (bossTimer >= global_data->getValue(DATA_BOSSDATA, magic, 25) * 0.01f) bossPhase = 10; //use teleport again } break; } }
void enemy::kingAI(float elapsed) { unsigned int totalBossResource = (unsigned int) ((1 - healthFraction()) / (global_data->getValue(DATA_BOSSDATA, magic, 0) * 0.01f)); switch(bossPhase) { case 0: case 1: case 2: if (!global_map->dialogueActive()) { global_map->forceDialogue(global_data->getValue(DATA_BOSSDATA, magic, 1) + bossPhase); bossPhase += 1; if (bossPhase == 3) { switchWeapon(); global_map->forceMusic(BOSSMUSIC); } } break; case 3: if (!global_map->dialogueActive()) { timer += elapsed; if (timer > global_data->getValue(DATA_BOSSDATA, magic, 9) * 0.01f) { bossTimer = 0; bossProb = 0; //pick a phase if ((unsigned int) bossResource < totalBossResource) { bossResource += 1; bossPhase = 4; } else { if (global_map->isMultiplayer()) bossProb = rand() % 2; else bossProb = 0; if (global_map->getCreature(bossProb)->dead()) bossProb = 1 - bossProb; if (global_map->getCreature(bossProb)->getX() < getX()) facingX = -1; else facingX = 1; if (rand() % 4 == 1) bossPhase = 7; else bossPhase = 5 + rand() % 2; } } } break; case 4: //summon { float bTOld = bossTimer; bossTimer += elapsed; float sPoint = global_data->getValue(DATA_BOSSDATA, magic, 2) * 0.01f; if (bossTimer >= sPoint && bTOld < sPoint) { //summon for (unsigned int i = 0; i < 2; i++) { float sX = global_data->getValue(DATA_BOSSDATA, magic, 4 + i) * 1.0f; float sY = global_map->getHeight() - (1 + GENERATOR_BOTTOMBORDER) * TILESIZE; unsigned int sTypeA = 0; if (bossResource > global_data->getValue(DATA_BOSSDATA, magic, 6)) sTypeA += 1; global_map->summon(sX, sY, global_data->getValue(DATA_BOSSDATA, magic, 7 + sTypeA), true, true); //it's a boss so it doesn't give EXP } } else if (bossTimer > global_data->getValue(DATA_BOSSDATA, magic, 3) * 0.01f) bossPhase = 3; //back to pick phase } break; case 5: { //swing if (bossTimer == 0) { startAttack(); creature *cr = global_map->getCreature(bossProb); if (abs(getX() - cr->getX()) > getMaskWidth() / 2) bossProb = facingX; else bossProb = 0; if (cr->getY() < getY()) jump(); } else if (!attacking()) bossPhase = 3; bossTimer += elapsed; if (bossProb != 0) move(bossProb, elapsed); } break; case 6: { if (bossTimer == 0) global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 10), TYPE_PLAYER); else if (bossTimer > global_data->getValue(DATA_BOSSDATA, magic, 11) * 0.01f) bossPhase = 3; bossTimer += elapsed; } break; case 7: { if (bossTimer == 0) global_map->magic(this, global_data->getValue(DATA_BOSSDATA, magic, 12), TYPE_PLAYER); else if (bossTimer > global_data->getValue(DATA_BOSSDATA, magic, 13) * 0.01f) bossPhase = 3; bossTimer += elapsed; } break; } }