Ejemplo n.º 1
0
bool Client::BindWound(Mob* bindtar,bool fail){
	APPLAYER* bwout_app = new APPLAYER(OP_BindWound,sizeof(BindWound_Struct));
	BindWound_Struct* bwout = (BindWound_Struct*)bwout_app->pBuffer;

	if(!fail){

		if(GetFeigned()){													// Break Feign Death for Bind Wound
			SetFeigned(false);												//
		}

		int cap = 50;														// Set % Cap/Heal Cap
		int hp_cap = bindtar->GetMaxHP()/2;									//
		if(GetClass() == MONK && GetSkill(BIND_WOUND) > 200){				//
			cap = 70;														//
			hp_cap += bindtar->GetMaxHP()/5;								//
		}
		if(!bindwound_timer->Enabled()){                                    // Begin Bind Wound
			
			if(bindtar->GetHP() >= hp_cap){									// INITIAL CAP CHECK
				Message(DARK_BLUE, "You cannot bandage your target past %d percent of their hit points.", cap);
				bwout->type = 3;											// 
				QueuePacket(bwout_app);										//
				bwout->type = 2;											//
				QueuePacket(bwout_app);										//
				safe_delete(bwout_app);										//
				return true;
			}

			int16 bndg_slot = FindItemTypeInInventory(ItemTypeBandage);			// Consume Bandage
			RemoveOneCharge(bndg_slot,true);								//

			bindwound_timer->Start(10000);									// Start Timer

			bindwound_target = bindtar;

			bwout->type = 3;												// Unlock Interface
			QueuePacket(bwout_app);											//
			bwout->type = 0;												//

			if(!bindtar){													// Target Dead
				bwout->type = 4;											//
				QueuePacket(bwout_app);										//
				bwout->type = 0;											//
				bindwound_timer->Disable();									//
				bindwound_target = 0;										//
			}
			else if(bindtar!=this)											// Send Bind Message to target if not binding self
				bindtar->CastToClient()->Message(DARK_BLUE,"You are being bandaged. Stay relatively still.");
		}
		else{																// END Bind Wound

			bindwound_timer->Disable();										// Stop Timer

			bindwound_target = 0;

			if(!bindtar){													// Target Not Found
				bwout->type = 5;											//
				QueuePacket(bwout_app);										//
				bwout->type = 0;											//
			}
			
			if((!GetFeigned() && bindtar->DistNoRoot(this->CastToMob()) <= 400)){ //// **** TAKEN FROM EQEMU, FD Check/Distance?
				bwout->type = 1;											// Finish Bind
				QueuePacket(bwout_app);										//
				bwout->type = 0;											//

				if(this!=bindtar)											// Message to target
					bindtar->CastToClient()->Message(YELLOW,"The bandaging is complete.");
	
				CheckAddSkill(BIND_WOUND);									// Check Skill Up



				if(bindtar->GetHP() < hp_cap){								// END CAP CHECK (Does not include heal amount)
					int heal = 3;											//   Set Heal Amount
					if(GetSkill(BIND_WOUND) > 200)							//   //
						heal += GetSkill(BIND_WOUND)*4/10;					//   //
					else if(GetSkill(BIND_WOUND) >= 10)						//   //
						heal += GetSkill(BIND_WOUND)/4;						//   //

					bindtar->SetHP(bindtar->GetHP()+heal);					// Set Hp + Update
					bindtar->SendHPUpdate();								//
				}
				else{														// Over Cap
					Message(DARK_BLUE, "You cannot bandage your target past %d percent of their hit points.", cap);
					if(this != bindtar)										//
						bindtar->CastToClient()->Message(DARK_BLUE, "You cannot be bandaged past %d percent of your max hit points.",cap);
				}
			}
			else if(bindtar!=this){											// Failed Moved/Moved Away
				bwout->type = 6;											//
				QueuePacket(bwout_app);										//
				bwout->type = 0;											//
			}
			else{

				//Feigned/Out of Range and binding self Not sure if anything needs to go here or not
			}
		}
	}
	else if(bindwound_timer->Enabled()){									// Failed: Ended Via Sit/Stand/Feign

		if(!GetFeigned()){													// Sit/Stand
			bindwound_timer->Disable();										//
			bwout->type = 3;												//
			QueuePacket(bwout_app);											//
			bwout->type = 7;												//
			QueuePacket(bwout_app);											//
		}
		else{
			bindwound_timer->Disable();										// Feign Death
			bindwound_target = 0;											//
			Message(YELLOW,"You have moved and your attempt to bandage has failed.");
		}
	}
	safe_delete(bwout_app);													// Delete packet
	return true;
}
Ejemplo n.º 2
0
void Client::ActivateAA(aaID activate){
	if (activate < 0 || activate >= aaHighestID)
		return;
	if (IsStunned() || IsFeared() || IsMezzed() || IsSilenced() || IsPet() || IsSitting() || GetFeigned())
		return;

	int AATimerID = GetAATimerID(activate);

	SendAA_Struct* aa2 = nullptr;
	aaID aaid = activate;
	uint8 activate_val = GetAA(activate);
	//this wasn't taking into acct multi tiered act talents before...
	if (activate_val == 0){
		aa2 = zone->FindAA(activate);
		if (!aa2){
			int i;
			int a;
			for (i = 1; i<MAX_AA_ACTION_RANKS; i++){
				a = activate - i;
				if (a <= 0)
					break;

				aa2 = zone->FindAA(a);
				if (aa2 != nullptr)
					break;
			}
		}
		if (aa2){
			aaid = (aaID)aa2->id;
			activate_val = GetAA(aa2->id);
		}
	}

	if (activate_val == 0){
		return;
	}

	if (aa2)
	{
		if (aa2->account_time_required)
		{
			if ((Timer::GetTimeSeconds() + account_creation) < aa2->account_time_required)
			{
				return;
			}
		}
	}

	if (!p_timers.Expired(&database, AATimerID + pTimerAAStart))
	{
		uint32 aaremain = p_timers.GetRemainingTime(AATimerID + pTimerAAStart);
		uint32 aaremain_hr = aaremain / (60 * 60);
		uint32 aaremain_min = (aaremain / 60) % 60;
		uint32 aaremain_sec = aaremain % 60;

		if (aa2) {
			if (aaremain_hr >= 1)	//1 hour or more
				Message(CC_Red, "You can use the ability %s again in %u hour(s) %u minute(s) %u seconds",
				aa2->name, aaremain_hr, aaremain_min, aaremain_sec);
			else	//less than an hour
				Message(CC_Red, "You can use the ability %s again in %u minute(s) %u seconds",
				aa2->name, aaremain_min, aaremain_sec);
		}
		else {
			if (aaremain_hr >= 1)	//1 hour or more
				Message(CC_Red, "You can use this ability again in %u hour(s) %u minute(s) %u seconds",
				aaremain_hr, aaremain_min, aaremain_sec);
			else	//less than an hour
				Message(CC_Red, "You can use this ability again in %u minute(s) %u seconds",
				aaremain_min, aaremain_sec);
		}
		return;
	}

	if (activate_val > MAX_AA_ACTION_RANKS)
		activate_val = MAX_AA_ACTION_RANKS;
	activate_val--;		//to get array index.

	//get our current node, now that the indices are well bounded
	const AA_DBAction *caa = &AA_Actions[aaid][activate_val];

	if ((aaid == aaImprovedHarmTouch || aaid == aaLeechTouch) && !p_timers.Expired(&database, pTimerHarmTouch)){
		Message(CC_Red, "Ability recovery time not yet met.");
		return;
	}

	//everything should be configured out now

	uint16 target_id = 0;

	//figure out our target
	switch (caa->target) {
	case aaTargetUser:
	case aaTargetGroup:
		target_id = GetID();
		break;
	case aaTargetCurrent:
	case aaTargetCurrentGroup:
		if (GetTarget() == nullptr) {
			Message_StringID(MT_DefaultText, AA_NO_TARGET);	//You must first select a target for this ability!
			p_timers.Clear(&database, AATimerID + pTimerAAStart);
			return;
		}
		target_id = GetTarget()->GetID();
		break;
	case aaTargetPet:
		if (GetPet() == nullptr) {
			Message(0, "A pet is required for this skill.");
			return;
		}
		target_id = GetPetID();
		break;
	}

	//handle non-spell action
	if (caa->action != aaActionNone) {
		if (caa->mana_cost > 0) {
			if (GetMana() < caa->mana_cost) {
				Message_StringID(CC_Red, INSUFFICIENT_MANA);
				return;
			}
			SetMana(GetMana() - caa->mana_cost);
		}
		if (caa->reuse_time > 0)
		{
			uint32 timer_base = CalcAAReuseTimer(caa);
			if (activate == aaImprovedHarmTouch || activate == aaLeechTouch)
			{
				p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime);
			}
			p_timers.Start(AATimerID + pTimerAAStart, timer_base);
			SendAATimer(activate, static_cast<uint32>(time(nullptr)), static_cast<uint32>(time(nullptr)));
		}
		HandleAAAction(aaid);
	}

	//cast the spell, if we have one
	if (caa->spell_id > 0 && caa->spell_id < SPDAT_RECORDS) {

		if (caa->reuse_time > 0)
		{
			uint32 timer_base = CalcAAReuseTimer(caa);
			SendAATimer(activate, static_cast<uint32>(time(nullptr)), static_cast<uint32>(time(nullptr)));
			p_timers.Start(AATimerID + pTimerAAStart, timer_base);
			if (activate == aaImprovedHarmTouch || activate == aaLeechTouch)
			{
				p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime);
			}
			// Bards can cast instant cast AAs while they are casting another song
			if (spells[caa->spell_id].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
				if (!SpellFinished(caa->spell_id, entity_list.GetMob(target_id), 10, -1, -1, spells[caa->spell_id].ResistDiff, false)) {
					//Reset on failed cast
					SendAATimer(activate, 0, 0xFFFFFF);
					Message_StringID(CC_Yellow, ABILITY_FAILED);
					p_timers.Clear(&database, AATimerID + pTimerAAStart);
					return;
				}
			}
			else {
				if (!CastSpell(caa->spell_id, target_id, USE_ITEM_SPELL_SLOT, -1, -1, 0, -1, AATimerID + pTimerAAStart, timer_base, 1)) {
					//Reset on failed cast
					SendAATimer(activate, 0, 0xFFFFFF);
					Message_StringID(CC_Yellow, ABILITY_FAILED);
					p_timers.Clear(&database, AATimerID + pTimerAAStart);
					return;
				}
			}
		}
		else
		{
			if (!CastSpell(caa->spell_id, target_id))
				return;
		}
	}
}
Ejemplo n.º 3
0
int32 Client::LevelRegen()
{
	bool sitting = IsSitting();
	bool feigned = GetFeigned();
	int level = GetLevel();
	bool bonus = GetRaceBitmask(GetBaseRace()) & RuleI(Character, BaseHPRegenBonusRaces);
	uint8 multiplier1 = bonus ? 2 : 1;
	int32 hp = 0;

	//these calculations should match up with the info from Monkly Business, which was last updated ~05/2008: http://www.monkly-business.net/index.php?pageid=abilities
	if (level < 51) {
		if (sitting) {
			if (level < 20)
				hp += 2 * multiplier1;
			else if (level < 50)
				hp += 3 * multiplier1;
			else	//level == 50
				hp += 4 * multiplier1;
		}
		else	//feigned or standing
			hp += 1 * multiplier1;
	}
	//there may be an easier way to calculate this next part, but I don't know what it is
	else {	//level >= 51
		int32 tmp = 0;
		float multiplier2 = 1;
		if (level < 56) {
			tmp = 2;
			if (bonus)
				multiplier2 = 3;
		}
		else if (level < 60) {
			tmp = 3;
			if (bonus)
				multiplier2 = 3.34;
		}
		else if (level < 61) {
			tmp = 4;
			if (bonus)
				multiplier2 = 3;
		}
		else if (level < 63) {
			tmp = 5;
			if (bonus)
				multiplier2 = 2.8;
		}
		else if (level < 65) {
			tmp = 6;
			if (bonus)
				multiplier2 = 2.67;
		}
		else {	//level >= 65
			tmp = 7;
			if (bonus)
				multiplier2 = 2.58;
		}

		hp += int32(float(tmp) * multiplier2);

		if (sitting)
			hp += 3 * multiplier1;
		else if (feigned)
			hp += 1 * multiplier1;
	}

	return hp;
}
Ejemplo n.º 4
0
//o--------------------------------------------------------------
//| Name: GetFactionLevel; rembrant, Dec. 16, 2001
//o--------------------------------------------------------------
//| Notes: Gets the characters faction standing with the
//|        specified NPC.
//|        Will return Indifferent on failure.
//o--------------------------------------------------------------
FACTION_VALUE Client::GetFactionLevel(int32 char_id, int32 npc_id, int32 p_race, int32 p_class, int32 p_deity, sint32 pFaction, Mob* tnpc)
{
	if (pFaction < 0)
		return GetSpecialFactionCon(tnpc);
	FACTION_VALUE fac = FACTION_INDIFFERENT;
	//sint32 pFacValue;  -Trumpcard: commenting. Not currently used.
	sint32 tmpFactionValue;
	FactionMods fmods;

    // neotokyo: few optimizations
    if (GetFeigned())
		return FACTION_INDIFFERENT;
    if (invisible_undead && tnpc && !tnpc->SeeInvisibleUndead())
        return FACTION_INDIFFERENT;
    if (IsInvisible(tnpc))
		return FACTION_INDIFFERENT;
    if (tnpc && tnpc->GetOwnerID() != 0) // neotokyo: pets always con indiff
        return FACTION_INDIFFERENT;
#ifdef GUILDWARS
	if(tnpc && tnpc->IsNPC() && tnpc->CastToNPC()->GetGuildOwner() != 0 && GuildDBID() != 0)
	{
		if(IsAttackAllowed(tnpc))
			return FACTION_SCOWLS;
		else
			return FACTION_ALLY;
	}
#endif

    //First get the NPC's Primary faction
	if(pFaction > 0)
	{
		//Get the faction data from the database
		if(database.GetFactionData(&fmods, p_class, p_race, p_deity, pFaction))
		{
			//Get the players current faction with pFaction
			tmpFactionValue = this->GetCharacterFactionLevel(pFaction);
			//Return the faction to the client
			fac = CalculateFaction(&fmods, tmpFactionValue);
			//Message(0,"Faction: %i %i %i %i",fmods.base,fmods.class_mod,fmods.race_mod,fmods.deity_mod);
			//Message(0,"tmpFactionValue: %i, fac: %i",tmpFactionValue,fac);
		}
	}
	else
    {
        fmods.base = 0;
        fmods.deity_mod = 0;

        if (tnpc && p_class == (int32) tnpc->GetClass()%16)
            fmods.class_mod = 301;
        else if (tnpc && tnpc->IsNPC() && tnpc->CastToNPC()->MerchantType == 0)
            fmods.class_mod = -101;
        else
            fmods.class_mod = 0;

        if (tnpc && IsOfEqualRace(p_race, tnpc->GetRace()) )
            fmods.race_mod = 101;
        else if (tnpc && IsOfIndiffRace(p_race, tnpc->GetRace()) )
            fmods.race_mod = 0;
        else if (tnpc)
            fmods.race_mod = -51;
        else
            fmods.race_mod = 0;
        fac = CalculateFaction(&fmods, 0);
    }

    // merchant fix
    if (tnpc && tnpc->IsNPC() && tnpc->CastToNPC()->MerchantType && (fac == FACTION_THREATENLY || fac == FACTION_SCOWLS))
        fac = FACTION_DUBIOUS;

	if (tnpc != 0 && fac != FACTION_SCOWLS && tnpc->CastToNPC()->CheckAggro(this))
		fac = FACTION_THREATENLY;

	return fac;
}