Example #1
0
bool Client::GenPassKey(char* key) {
	char* passKey=nullptr;
	*passKey += ((char)('A'+((int)MakeRandomInt(0, 25))));
	*passKey += ((char)('A'+((int)MakeRandomInt(0, 25))));
	memcpy(key, passKey, strlen(passKey));
	return true;
}
Example #2
0
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {

	//Scale all NPC spell healing via SetSpellFocusHeal(value)

	value += value*SpellFocusHeal/100; 

	 if (target) {
		value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id); 
		value += value*target->GetHealRate(spell_id, this)/100;
	 }

	 //Allow for critical heal chance if NPC is loading spell effect bonuses.
	 if (AI_HasSpellsEffects()){

		if(spells[spell_id].buffduration < 1) {

			if(spellbonuses.CriticalHealChance && (MakeRandomInt(0,99) < spellbonuses.CriticalHealChance)) {
				value = value*2;	 			
				entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_HEAL, GetCleanName(), itoa(value));
			}
		}
		else if(spellbonuses.CriticalHealOverTime && (MakeRandomInt(0,99) < spellbonuses.CriticalHealOverTime)) {
				value = value*2;	 			
		}
	 }
	 
	return value;
}
Example #3
0
bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {

	/*
	Charm formula is correct based on over 50 hours of personal live parsing - Kayen
	Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 200 CHA
	Charisma DOES NOT extend charm durations.
	Base effect value of charm spells in the spell file DOES NOT effect duration OR resist rate (unclear if does anything)
	Charm has a lower limit of 5% chance to break per tick, regardless of resist modifiers / level difference.
	*/

	if(!caster) return false;

	if(spells[spell_id].ResistDiff <= -600)
		return true;

	float resist_check = 0;
	
	if(IsCharmSpell(spell_id)) {

		if (spells[spell_id].powerful_flag == -1) //If charm spell has this set(-1), it can not break till end of duration.
			return true;

		//1: The mob has a default 25% chance of being allowed a resistance check against the charm.
		if (MakeRandomInt(0, 99) > RuleI(Spells, CharmBreakCheckChance))
			return true;

		if (RuleB(Spells, CharismaCharmDuration))
			resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,0,0,true,true);
		else
			resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, 0,0, false, true);

		//2: The mob makes a resistance check against the charm
		if (resist_check == 100) 
			return true;

		else
		{
			if (caster->IsClient())
			{
				//3: At maxed ability, Total Domination has a 50% chance of preventing the charm break that otherwise would have occurred.
				int16 TotalDominationBonus = caster->aabonuses.CharmBreakChance + caster->spellbonuses.CharmBreakChance + caster->itembonuses.CharmBreakChance;

				if (MakeRandomInt(0, 99) < TotalDominationBonus)
					return true;

			}
		}
	}

	else
	{
		// Assume this is a harmony/pacify spell
		resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster);

		if (resist_check == 100)
			return true;
	}

	return false;
}
Example #4
0
void Mob::CalculateNewFearpoint()
{
	if(RuleB(Pathing, Fear) && zone->pathing)
	{
		int Node = zone->pathing->GetRandomPathNode();
	
		VERTEX Loc = zone->pathing->GetPathNodeCoordinates(Node);

		++Loc.z;

		VERTEX CurrentPosition(GetX(), GetY(), GetZ());

		list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);

		if(Route.size() > 0)
		{
			fear_walkto_x = Loc.x;
			fear_walkto_y = Loc.y;
			fear_walkto_z = Loc.z;
			curfp = true;

			mlog(PATHING__DEBUG, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
			return;
		}

		mlog(PATHING__DEBUG, "No path found to selected node. Falling through to old fear point selection.");
	}

	int loop = 0;
	float ranx, rany, ranz;
	curfp = false;
	while (loop < 100) //Max 100 tries
	{
		int ran = 250 - (loop*2);
		loop++;
		ranx = GetX()+MakeRandomInt(0, ran-1)-MakeRandomInt(0, ran-1);
		rany = GetY()+MakeRandomInt(0, ran-1)-MakeRandomInt(0, ran-1);
		ranz = FindGroundZ(ranx,rany);
		if (ranz == -999999)
			continue;
		float fdist = ranz - GetZ();
		if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
		{
			curfp = true;
			break;
		}
	}
	if (curfp)
	{
		fear_walkto_x = ranx;
		fear_walkto_y = rany;
		fear_walkto_z = ranz;
	}
	else //Break fear
	{
		BuffFadeByEffect(SE_Fear);
	}
}
Example #5
0
Mob* EntityList::GetTrapTrigger(Trap* trap) {
	Mob* savemob = 0;

	float xdiff, ydiff, zdiff;

	float maxdist = trap->radius * trap->radius;

	auto it = client_list.begin();
	while (it != client_list.end()) {
		Client* cur = it->second;
		zdiff = cur->GetZ() - trap->z;
		if(zdiff < 0)
			zdiff = 0 - zdiff;

		xdiff = cur->GetX() - trap->x;
		ydiff = cur->GetY() - trap->y;
		if ((xdiff*xdiff + ydiff*ydiff) <= maxdist
			&& zdiff < trap->maxzdiff)
		{
			if (MakeRandomInt(0,100) < trap->chance)
				return(cur);
			else
				savemob = cur;
		}
		++it;
	}
	return savemob;
}
Example #6
0
int32 Client::GetActDoTDamage(uint16 spell_id, int32 value) {

    int32 modifier = 100;
    int16 spell_dmg = 0;
    int16 critChance = 0;
    int32 ratio = 0;

    modifier += GetFocusEffect(focusImprovedDamage, spell_id);
    critChance += itembonuses.CriticalDoTChance + spellbonuses.CriticalDoTChance + aabonuses.CriticalDoTChance;
    ratio += itembonuses.DotCritDmgIncrease + spellbonuses.DotCritDmgIncrease + aabonuses.DotCritDmgIncrease;
    spell_dmg += Additional_SpellDmg(spell_id,true);

    // since DOTs are the Necromancer forte, give an innate bonus (Kayen: Is this a real bonus?)
    // however, no chance to crit unless they've trained atleast one level in the AA first
    if (GetClass() == NECROMANCER && critChance > 0)
        critChance += 5;

    if (critChance > 0) {
        if (MakeRandomInt(0, 99) < critChance) {
            modifier += modifier*ratio/100;
            return (((value*modifier/100)-spell_dmg)*2);
        }
    }

    return ((value*modifier/100)-spell_dmg);

}
Example #7
0
Mob* EntityList::GetTrapTrigger(Trap* trap) {
	LinkedListIterator<Client*> iterator(client_list);

	Mob* savemob = 0;
	iterator.Reset();
	
	float xdiff, ydiff, zdiff;
	
	float maxdist = trap->radius * trap->radius;
	
	while(iterator.MoreElements()) {
		Client* cur = iterator.GetData();
		zdiff = cur->GetZ() - trap->z;
		if(zdiff < 0)
			zdiff = 0 - zdiff;
		
		xdiff = cur->GetX() - trap->x;
		ydiff = cur->GetY() - trap->y;
		if ((xdiff*xdiff + ydiff*ydiff) <= maxdist
			&& zdiff < trap->maxzdiff)
		{
			if (MakeRandomInt(0,100) < trap->chance)
				return(cur);
			else
				savemob = cur;
		}
		iterator.Advance();
	}
	return savemob;
}
Example #8
0
int32 NPC::GetActSpellDamage(uint16 spell_id, int32 value,  Mob* target) {

	//Quest scale all NPC spell damage via $npc->SetSpellFocusDMG(value)
	//DoT Damage - Mob::DoBuffTic [spell_effects.cpp] / Direct Damage Mob::SpellEffect [spell_effects.cpp]

	int32 dmg = value;

	 if (target) {
		value += dmg*target->GetVulnerability(this, spell_id, 0)/100; 

		if (spells[spell_id].buffduration == 0)
			value -= target->GetFcDamageAmtIncoming(this, spell_id);
		else
			value -= target->GetFcDamageAmtIncoming(this, spell_id)/spells[spell_id].buffduration;
	 }
	  	 
	 value += dmg*SpellFocusDMG/100; 

	if (AI_HasSpellsEffects()){
		int16 chance = 0;
		int ratio = 0;

		if (spells[spell_id].buffduration == 0) {
		
			chance += spellbonuses.CriticalSpellChance + spellbonuses.FrenziedDevastation;
		
			if (chance && MakeRandomInt(1,100) <= chance){
			
				ratio += spellbonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncNoStack;
				value += (value*ratio)/100;
				entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_BLAST, GetCleanName(), itoa(-value));
			}
		}
		else {
			
			chance += spellbonuses.CriticalDoTChance;
		
			if (chance && MakeRandomInt(1,100) <= chance){
			
				ratio += spellbonuses.DotCritDmgIncrease;
				value += (value*ratio)/100;
			}
		}
	}

	return value;
}
Example #9
0
bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {

	if(!caster) return false;

	if(spells[spell_id].ResistDiff <= -600)
		return true;

	//Applies additional Charisma bonus to resist rate
	float resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,0,0,1);

	if(IsCharmSpell(spell_id)) {

		if (spells[spell_id].powerful_flag == -1) //If charm spell has this set(-1), it can not break till end of duration.
			return true;

		//1: The mob has a default 25% chance of being allowed a resistance check against the charm.
		if (MakeRandomInt(0, 100) > RuleI(Spells, CharmBreakCheckChance))
			return true;

		//2: The mob makes a resistance check against the charm
		if (resist_check == 100)
			return true;

		else
		{
			if (caster->IsClient())
			{
				//3: At maxed ability, Total Domination has a 50% chance of preventing the charm break that otherwise would have occurred.
				uint16 TotalDominationBonus = caster->aabonuses.CharmBreakChance + caster->spellbonuses.CharmBreakChance + caster->itembonuses.CharmBreakChance;

				if (MakeRandomInt(0, 100) < TotalDominationBonus)
					return true;

			}
		}
	}

	else
	{
		// Assume this is a harmony/pacify spell
		if (resist_check == 100)
			return true;
	}

	return false;
}
Example #10
0
std::string APIAccountManager::_GenerateAPIKey()
{
    std::string key = "";

    for( int i=0; i<64; i++ )
        key += m_hexCharMap.substr(static_cast<uint16>(MakeRandomInt(0, 15)), 1);

    return key;
}
Example #11
0
int32 Client::GetActSpellHealing(uint16 spell_id, int32 value) {

    int32 modifier = 100;
    int16 heal_amt = 0;
    modifier += GetFocusEffect(focusImprovedHeal, spell_id);
    modifier += GetFocusEffect(focusSpellEffectiveness, spell_id);
    heal_amt += Additional_Heal(spell_id);
    int chance = 0;

    // Instant Heals
    if(spells[spell_id].buffduration < 1)
    {
        // Formula = HealAmt * (casttime + recastime) / 7; Cant trigger off spell less than 5 levels below and cant heal more than the spell itself.
        if(this->itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) {
            heal_amt = this->itembonuses.HealAmt * (spells[spell_id].cast_time + spells[spell_id].recast_time) / 7000;
            if(heal_amt > value)
                heal_amt = value;
        }

        // Check for buffs that affect the healrate of the target and critical heal rate of target
        if(GetTarget()) {
            value += value * GetHealRate(spell_id) / 100;
            chance += GetCriticalHealRate(spell_id);
        }

        //Live AA - Healing Gift, Theft of Life
        chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;

        if(MakeRandomInt(0,99) < chance) {
            entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), ((value * modifier / 50) + heal_amt*2));
            return ((value * modifier / 50) + heal_amt*2);
        }
        else {
            return ((value * modifier / 100) + heal_amt);
        }
    }
    // Hots
    else {
        chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
        if(MakeRandomInt(0,99) < chance)
            return ((value * modifier / 50) + heal_amt*2);
    }
    return ((value * modifier / 100) + heal_amt);
}
Example #12
0
// This allows EqEmu to have zone specific foraging - BoB
uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	uint8 index = 0;
	uint32 item[FORAGE_ITEM_LIMIT];
	uint32 chance[FORAGE_ITEM_LIMIT];
	uint32 ret;

	for (int c=0; c < FORAGE_ITEM_LIMIT; c++) {
		item[c] = 0;
	}

	uint32 chancepool = 0;

	if (RunQuery(query, MakeAnyLenString(&query, "SELECT itemid,chance FROM forage WHERE zoneid= '%i' and level <= '%i' LIMIT %i", ZoneID, skill, FORAGE_ITEM_LIMIT), errbuf, &result))
	{
		safe_delete_array(query);
		while ((row = mysql_fetch_row(result)) && (index < FORAGE_ITEM_LIMIT)) {
			item[index] = atoi(row[0]);
			chance[index] = atoi(row[1])+chancepool;
LogFile->write(EQEMuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
			chancepool = chance[index];
			index++;
		}

		mysql_free_result(result);
	}
	else {
		LogFile->write(EQEMuLog::Error, "Error in Forage query '%s': %s", query, errbuf);
		safe_delete_array(query);
		return 0;
	}

	if(chancepool == 0 || index < 1)
		return(0);

	if(index == 1) {
		return(item[0]);
	}

	ret = 0;

	uint32 rindex = MakeRandomInt(1, chancepool);

	for(int i = 0; i < index; i++) {
		if(rindex <= chance[i]) {
			ret = item[i];
			break;
		}
	}

	return ret;
}
Example #13
0
Mob *HateList::GetRandom()
{
	int count = list.size();
	auto iterator = list.begin();
	int random = MakeRandomInt(0, count - 1);
	for (int i = 0; i < random; i++)
		++iterator;
	
	return (*iterator)->ent;
}
Example #14
0
uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, uint8 &npc_chance)
{
	uint32 item[50];
	uint32 chance[50];
	uint32 npc_ids[50];
	uint32 npc_chances[50];
	uint32 chancepool = 0;
	uint32 ret = 0;

	for (int c=0; c<50; c++) {
		item[c]=0;
		chance[c]=0;
	}

    std::string query = StringFormat("SELECT itemid, chance, npc_id, npc_chance "
                                    "FROM fishing WHERE (zoneid = '%i' || zoneid = 0) AND skill_level <= '%i'",
                                    ZoneID, skill);
    auto results = QueryDatabase(query);
    if (!results.Success()) {
        std::cerr << "Error in Fishing query '" << query << "' " << results.ErrorMessage() << std::endl;
		return 0;
    }

    uint8 index = 0;
    for (auto row = results.begin(); row != results.end(); ++row, ++index) {
        if (index >= 50)
            break;

        item[index] = atoi(row[0]);
        chance[index] = atoi(row[1])+chancepool;
        chancepool = chance[index];

        npc_ids[index] = atoi(row[2]);
        npc_chances[index] = atoi(row[3]);
    }

	npc_id = 0;
	npc_chance = 0;
	if (index <= 0)
        return 0;

    uint32 random = MakeRandomInt(1, chancepool);
    for (int i = 0; i < index; i++)
    {
        if (random > chance[i])
            continue;

        ret = item[i];
        npc_id = npc_ids[i];
        npc_chance = npc_chances[i];
        break;
    }

	return ret;
}
std::string GenerateKey( size_t length )
{
    static const char CHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    static const size_t CHARS_COUNT = sizeof( CHARS ) / sizeof( char );

    std::string key;

    for(; 0 < length; --length)
        key += CHARS[ MakeRandomInt( 0, CHARS_COUNT - 1 ) ];

    return key;
}
Example #16
0
// This allows EqEmu to have zone specific foraging - BoB
uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {

	uint32 item[FORAGE_ITEM_LIMIT];
	uint32 chance[FORAGE_ITEM_LIMIT];
	uint32 ret;

	for (int c=0; c < FORAGE_ITEM_LIMIT; c++) {
		item[c] = 0;
	}

	uint32 chancepool = 0;
    std::string query = StringFormat("SELECT itemid, chance FROM "
                                    "forage WHERE zoneid = '%i' and level <= '%i' "
                                    "LIMIT %i", ZoneID, skill, FORAGE_ITEM_LIMIT);
    auto results = QueryDatabase(query);
	if (!results.Success()) {
        LogFile->write(EQEMuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
		return 0;
	}

	uint8 index = 0;
    for (auto row = results.begin(); row != results.end(); ++row, ++index) {
        if (index >= FORAGE_ITEM_LIMIT)
            break;

        item[index] = atoi(row[0]);
        chance[index] = atoi(row[1]) + chancepool;
        LogFile->write(EQEMuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
        chancepool = chance[index];
    }


	if(chancepool == 0 || index < 1)
		return 0;

	if(index == 1) {
		return item[0];
	}

	ret = 0;

	uint32 rindex = MakeRandomInt(1, chancepool);

	for(int i = 0; i < index; i++) {
		if(rindex <= chance[i]) {
			ret = item[i];
			break;
		}
	}

	return ret;
}
Example #17
0
uint32 Spawn2::despawnTimer(uint32 despawn_timer)
{
	uint32 dspawn = despawn_timer * 1000;
	
	if (variance_ != 0) {
		int var_over_2 = (variance_ * 1000) / 2;
		dspawn = MakeRandomInt(dspawn - var_over_2, dspawn + var_over_2);
		
		//put a lower bound on it, not a lot of difference below 100, so set that as the bound.
		if(dspawn < 100)
			dspawn = 100;
	}
	
	return (dspawn);
	
}
Example #18
0
uint32 Spawn2::resetTimer()
{
	uint32 rspawn = respawn_ * 1000;
	
	if (variance_ != 0) {
		int var_over_2 = (variance_ * 1000) / 2;
		rspawn = MakeRandomInt(rspawn - var_over_2, rspawn + var_over_2);
		
		//put a lower bound on it, not a lot of difference below 100, so set that as the bound.
		if(rspawn < 100)
			rspawn = 100;
	}
	
	return (rspawn);
	
}
Example #19
0
void SpawnEntry::SpawnDepoped(uint32 npcID) {
	std::set<uint32>::iterator res;
	res = m_spawnedIDs.find(npcID);

	if(res == m_spawnedIDs.end()) {
		_log(SPAWN__ERROR, "SpawnDepopped() called for NPC %u on spawn entry %u, but that NPC is not in our spawned list.", npcID, m_id);
	} else {
		_log(SPAWN__DEPOP, "NPC %u depopped for spawn entry %u", npcID, m_id);
		m_spawnedIDs.erase(res);
	}
	
	if(m_spawnedIDs.empty()) {
		int timer = MakeRandomInt(m_timerMin, m_timerMax);
		_log(SPAWN__DEPOP, "Spawn entry %u's entire spawn group has depopped, resetting timer to %d s.", m_id, timer);
		m_timer.Start(timer*1000);
	}
}
PyResult Command_spawnbelt( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args )
{
	if( !who->IsInSpace() )
		throw PyException( MakeCustomError( "You must be in space to spawn things." ) );

    const double beltradius = 100000.0;
	const double beltdistance = 25000.0;
	const double roidradius = MakeRandomFloat( 100.0, 1000.0 );
	const double beltangle = M_PI * 2.0 / 3.0;
	const uint32 pcs = 20 + MakeRandomInt( -10, 10 );   // reduced from 160 + MakeRandomInt( -10, 10 )

	const GPoint position( who->GetPosition() );

	const double R = sqrt( position.x * position.x + position.z * position.z );
	const GPoint r = position * ( R + beltdistance - beltradius ) / R;

	double phi = atan( position.x / position.z );
	if( position.z < 0 )
		phi += M_PI;

	SystemManager* sys = who->System();
	std::map<double, uint32> roidDist;
	if( !db->GetRoidDist( sys->GetSystemSecurity(), roidDist ) )
    {
        sLog.Error( "Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity() );

		throw PyException( MakeCustomError( "Couldn't get roid list for system security %s", sys->GetSystemSecurity() ) );
	}

    //double distanceToMe;
	double alpha;
    GPoint mposition;

	for( uint32 i = 0; i < pcs; ++i )
    {
		alpha = beltangle * MakeRandomFloat( -0.5, 0.5 );

		mposition.x = beltradius * sin( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
		mposition.z = beltradius * cos( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
		mposition.y = position.y - r.y + roidradius * MakeRandomFloat( 0, 15 );
        //distanceToMe = (r + mposition - position).length();
        SpawnAsteroid( who->System(), GetAsteroidType( MakeRandomFloat(), roidDist ), roidradius, r + mposition );
	}

	return new PyString( "Spawn successsfull." );
}
Example #21
0
Mob *HateList::GetRandom()
{
    int count = 0;
    LinkedListIterator<tHateEntry*> iterator(list);
    iterator.Reset();
	while(iterator.MoreElements())
    {
        iterator.Advance();
        count++;
    }
	if(!count)
		return NULL;

    int random = MakeRandomInt(0, count-1);
    iterator.Reset();
    for (int i = 0; i < random-1; i++)
        iterator.Advance();
    return iterator.GetData()->ent;
}
Example #22
0
void Client::GenerateKey()
{
	key.clear();
	int count = 0;
	while(count < 10)
	{
		static const char key_selection[] = 
		{
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 
			'Y', 'Z', '0', '1', '2', '3', '4', '5', 
			'6', '7', '8', '9'
		};

		key.append((const char*)&key_selection[MakeRandomInt(0, 35)], 1);
		count++;
	}
}
Example #23
0
Mob *HateList::GetRandom()
{
	int count = list.size();
	if(count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
		return nullptr;

	if(count == 1) //No need to do all that extra work if we only have one hate entry
	{
		if(*list.begin()) // Just in case tHateEntry is invalidated somehow...
			return (*list.begin())->ent;

		return nullptr;
	}

	auto iterator = list.begin();
	int random = MakeRandomInt(0, count - 1);
	for (int i = 0; i < random; i++)
		++iterator;
	
	return (*iterator)->ent;
}
Example #24
0
uint32 SpawnGroup::GetNPCType() {
	int npcType = 0;
	int totalchance = 0;

	if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
		return(0);

	std::list<SpawnEntry*>::iterator cur,end;
	std::list<SpawnEntry*> possible;
	cur = list_.begin();
	end = list_.end();
	for(; cur != end; ++cur) {
		SpawnEntry *se = *cur;

		if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
			continue;

		totalchance += se->chance;
		possible.push_back(se);
	}
	if(totalchance == 0)
		return 0;


	int32 roll = 0;
	roll = MakeRandomInt(0, totalchance-1);

	cur = possible.begin();
	end = possible.end();
	for(; cur != end; ++cur) {
		SpawnEntry *se = *cur;
		if (roll < se->chance) {
			npcType = se->NPCType;
			break;
		} else {
			roll -= se->chance;
		}
	}
	return npcType;
}
Example #25
0
void ZSList::RebootZone(const char* ip1,uint16 port,const char* ip2, uint32 skipid, uint32 zoneid){
// get random zone
	LinkedListIterator<ZoneServer*> iterator(list);
	uint32 x = 0;
	iterator.Reset();
	while(iterator.MoreElements()) {
		x++;
		iterator.Advance();
	}
	if (x == 0)
		return;
	ZoneServer** tmp = new ZoneServer*[x];
	uint32 y = 0;
	iterator.Reset();
	while(iterator.MoreElements()) {
		if (!strcmp(iterator.GetData()->GetCAddress(),ip2) && !iterator.GetData()->IsBootingUp() && iterator.GetData()->GetID() != skipid) {
			tmp[y++] = iterator.GetData();
		}
		iterator.Advance();
	}
	if (y == 0) {
		safe_delete(tmp);
		return;
	}
	uint32 z = MakeRandomInt(0, y-1);

	ServerPacket* pack = new ServerPacket(ServerOP_ZoneReboot, sizeof(ServerZoneReboot_Struct));
	ServerZoneReboot_Struct* s = (ServerZoneReboot_Struct*) pack->pBuffer;
//	strcpy(s->ip1,ip1);
	strcpy(s->ip2,ip2);
	s->port = port;
	s->zoneid = zoneid;
	if(zoneid != 0)
		_log(WORLD__ZONELIST,"Rebooting static zone with the ID of: %i",zoneid);
	tmp[z]->SendPacket(pack);
	delete pack;
	safe_delete_array(tmp);
}
Example #26
0
int32 Client::GetActSpellDamage(uint16 spell_id, int32 value) {
    // Important variables:
    // value: the actual damage after resists, passed from Mob::SpellEffect
    // modifier: modifier to damage (from spells & focus effects?)
    // ratio: % of the modifier to apply (from AAs & natural bonus?)
    // chance: critital chance %

    int32 modifier = 100;
    int16 spell_dmg = 0;


    //Dunno if this makes sense:
    if (spells[spell_id].resisttype > 0)
        modifier += GetFocusEffect((focusType)(0-spells[spell_id].resisttype), spell_id);


    int tt = spells[spell_id].targettype;
    if (tt == ST_UndeadAE || tt == ST_Undead || tt == ST_Summoned) {
        //undead/summoned spells
        modifier += GetFocusEffect(focusImprovedUndeadDamage, spell_id);
    } else {
        //damage spells.
        modifier += GetFocusEffect(focusImprovedDamage, spell_id);
        modifier += GetFocusEffect(focusSpellEffectiveness, spell_id);
        modifier += GetFocusEffect(focusImprovedDamage2, spell_id);
    }

    // Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
    if ( spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH ) {
        if (this->GetLevel() > 40)
            value -= (this->GetLevel() - 40) * 20;
    }

    //This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
    if (spell_id == SPELL_IMP_HARM_TOUCH) {  //Improved Harm Touch
        value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
    }

    // This adds the extra damage for the AA's Consumption of the Soul and Improved Consumption of the Soul, 200 per level to the AA Leech Curse for Shadowknights.
    if (spell_id == SPELL_LEECH_TOUCH) {   //Leech Touch
        value -= GetAA(aaConsumptionoftheSoul) * 200; //Consumption of the Soul
        value -= GetAA(aaImprovedConsumptionofSoul) * 200; //Improved Consumption of the Soul
    }

    //spell crits, dont make sense if cast on self.
    if(tt != ST_Self) {
        // item SpellDmg bonus
        // Formula = SpellDmg * (casttime + recastime) / 7; Cant trigger off spell less than 5 levels below and cant cause more dmg than the spell itself.
        if(this->itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) {
            spell_dmg = this->itembonuses.SpellDmg * (spells[spell_id].cast_time + spells[spell_id].recast_time) / 7000;
            if(spell_dmg > -value)
                spell_dmg = -value;
        }

        // Spell-based SpellDmg adds directly but it restricted by focuses.
        spell_dmg += Additional_SpellDmg(spell_id);

        int chance = RuleI(Spells, BaseCritChance);
        int32 ratio = RuleI(Spells, BaseCritRatio);

        chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
        ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;

        if(GetClass() == WIZARD) {
            if (GetLevel() >= RuleI(Spells, WizCritLevel)) {
                chance += RuleI(Spells, WizCritChance);
                ratio += RuleI(Spells, WizCritRatio);
            }
            if(aabonuses.SpellCritDmgIncrease > 0) // wizards get an additional bonus
                ratio +=  aabonuses.SpellCritDmgIncrease * 1.5; //108%, 115%, 124%, close to Graffe's 207%, 215%, & 225%
        }

        //Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
        if (spell_id == SPELL_IMP_HARM_TOUCH) {
            if ( (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0) )
                chance = 100;
        }

        /*
        //Handled in aa_effects will focus spells from 'spellgroup=99'. (SK life tap from buff procs)
        //If you are using an older spell file table (Pre SOF)...
        //Use SQL optional_EnableSoulAbrasionAA to update your spells table to properly use the effect.
        //If you do not want to update your table then you may want to enable this.
        if(tt == ST_Tap) {
        	if(spells[spell_id].classes[SHADOWKNIGHT-1] >= 254 && spell_id != SPELL_LEECH_TOUCH){
        		if(ratio < 100)	//chance increase and ratio are made up, not confirmed
        			ratio = 100;

        		switch (GetAA(aaSoulAbrasion))
        		{
        		case 1:
        			modifier += 100;
        			break;
        		case 2:
        			modifier += 200;
        			break;
        		case 3:
        			modifier += 300;
        			break;
        		}
        	}
        }
        */

        if (chance > 0) {
            mlog(SPELLS__CRITS, "Attempting spell crit. Spell: %s (%d), Value: %d, Modifier: %d, Chance: %d, Ratio: %d", spells[spell_id].name, spell_id, value, modifier, chance, ratio);
            if(MakeRandomInt(0,100) <= chance) {
                modifier += modifier*ratio/100;
                spell_dmg *= 2;
                mlog(SPELLS__CRITS, "Spell crit successful. Final damage modifier: %d, Final Damage: %d", modifier, (value * modifier / 100) - spell_dmg);
                entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s delivers a critical blast! (%d)", GetName(), (-value * modifier / 100) + spell_dmg);
            } else
                mlog(SPELLS__CRITS, "Spell crit failed. Final Damage Modifier: %d, Final Damage: %d", modifier, (value * modifier / 100) - spell_dmg);
        }
    }

    return ((value * modifier / 100) - spell_dmg);
}
Example #27
0
int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
{
    // Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
    if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
    {
        int16 mana_back = this->itembonuses.Clairvoyance * MakeRandomInt(1, 100) / 100;
        // Doesnt generate mana, so best case is a free spell
        if(mana_back > cost)
            mana_back = cost;

        cost -= mana_back;
    }

    // This formula was derived from the following resource:
    // http://www.eqsummoners.com/eq1/specialization-library.html
    // WildcardX
    float PercentManaReduction = 0;
    float SpecializeSkill = GetSpecializeSkillValue(spell_id);
    int SuccessChance = MakeRandomInt(0, 100);

    float bonus = 1.0;
    switch(GetAA(aaSpellCastingMastery))
    {
    case 1:
        bonus += 0.05;
        break;
    case 2:
        bonus += 0.15;
        break;
    case 3:
        bonus += 0.30;
        break;
    }

    bonus += 0.05 * GetAA(aaAdvancedSpellCastingMastery);

    if(SuccessChance <= (SpecializeSkill * 0.3 * bonus))
    {
        PercentManaReduction = 1 + 0.05 * SpecializeSkill;
        switch(GetAA(aaSpellCastingMastery))
        {
        case 1:
            PercentManaReduction += 2.5;
            break;
        case 2:
            PercentManaReduction += 5.0;
            break;
        case 3:
            PercentManaReduction += 10.0;
            break;
        }

        switch(GetAA(aaAdvancedSpellCastingMastery))
        {
        case 1:
            PercentManaReduction += 2.5;
            break;
        case 2:
            PercentManaReduction += 5.0;
            break;
        case 3:
            PercentManaReduction += 10.0;
            break;
        }
    }

    int16 focus_redux = GetFocusEffect(focusManaCost, spell_id);

    if(focus_redux > 0)
    {
        PercentManaReduction += MakeRandomFloat(1, (double)focus_redux);
    }

    cost -= (cost * (PercentManaReduction / 100));

    // Gift of Mana - reduces spell cost to 1 mana
    if(focus_redux >= 100) {
        uint32 buff_max = GetMaxTotalSlots();
        for (int buffSlot = 0; buffSlot < buff_max; buffSlot++) {
            if (buffs[buffSlot].spellid == 0 || buffs[buffSlot].spellid >= SPDAT_RECORDS)
                continue;

            if(IsEffectInSpell(buffs[buffSlot].spellid, SE_ReduceManaCost)) {
                if(CalcFocusEffect(focusManaCost, buffs[buffSlot].spellid, spell_id) == 100)
                    cost = 1;
            }
        }
    }

    if(cost < 0)
        cost = 0;

    return cost;
}
Example #28
0
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {

	if (GetAccountID() == 0) {
		clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
		eqs->Close();
		return true;
	}

	if(GetAdmin() < 0)
	{
		clog(WORLD__CLIENT,"Account banned or suspended.");
		eqs->Close();
		return true;
	}

	if (RuleI(World, MaxClientsPerIP) >= 0) {
		client_list.GetCLEIP(this->GetIP()); //Check current CLE Entry IPs against incoming connection
	}

	EnterWorld_Struct *ew=(EnterWorld_Struct *)app->pBuffer;
	strn0cpy(char_name, ew->name, 64);

	EQApplicationPacket *outapp;
	uint32 tmpaccid = 0;
	charid = database.GetCharacterInfo(char_name, &tmpaccid, &zoneID, &instanceID);
	if (charid == 0 || tmpaccid != GetAccountID()) {
		clog(WORLD__CLIENT_ERR,"Could not get CharInfo for '%s'",char_name);
		eqs->Close();
		return true;
	}

	// Make sure this account owns this character
	if (tmpaccid != GetAccountID()) {
		clog(WORLD__CLIENT_ERR,"This account does not own the character named '%s'",char_name);
		eqs->Close();
		return true;
	}

	if(!pZoning && ew->return_home && !ew->tutorial)
	{
		CharacterSelect_Struct* cs = new CharacterSelect_Struct;
		memset(cs, 0, sizeof(CharacterSelect_Struct));
		database.GetCharSelectInfo(GetAccountID(), cs);
		bool home_enabled = false;

		for(int x = 0; x < 10; ++x)
		{
			if(strcasecmp(cs->name[x], char_name) == 0)
			{
				if(cs->gohome[x] == 1)
				{
					home_enabled = true;
					break;
				}
			}
		}
		safe_delete(cs);

		if(home_enabled)
		{
			zoneID = database.MoveCharacterToBind(charid,4);
		}
		else
		{
			clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name);
			database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
			eqs->Close();
			return true;
		}
	}

	if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) {
		CharacterSelect_Struct* cs = new CharacterSelect_Struct;
		memset(cs, 0, sizeof(CharacterSelect_Struct));
		database.GetCharSelectInfo(GetAccountID(), cs);
		bool tutorial_enabled = false;

		for(int x = 0; x < 10; ++x)
		{
			if(strcasecmp(cs->name[x], char_name) == 0)
			{
				if(cs->tutorial[x] == 1)
				{
					tutorial_enabled = true;
					break;
				}
			}
		}
		safe_delete(cs);

		if(tutorial_enabled)
		{
			zoneID = RuleI(World, TutorialZoneID);
			database.MoveCharacterToZone(charid, database.GetZoneName(zoneID));
		}
		else
		{
			clog(WORLD__CLIENT_ERR,"'%s' is trying to go to tutorial but are not allowed...",char_name);
			database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.");
			eqs->Close();
			return true;
		}
	}

	if (zoneID == 0 || !database.GetZoneName(zoneID)) {
		// This is to save people in an invalid zone, once it's removed from the DB
		database.MoveCharacterToZone(charid, "arena");
		clog(WORLD__CLIENT_ERR, "Zone not found in database zone_id=%i, moveing char to arena character:%s", zoneID, char_name);
	}

	if(instanceID > 0)
	{
		if(!database.VerifyInstanceAlive(instanceID, GetCharID()))
		{
			zoneID = database.MoveCharacterToBind(charid);
			instanceID = 0;
		}
		else
		{
			if(!database.VerifyZoneInstance(zoneID, instanceID))
			{
				zoneID = database.MoveCharacterToBind(charid);
				instanceID = 0;
			}
		}
	}

	if(!pZoning) {
		database.SetGroupID(char_name, 0, charid);
		database.SetFirstLogon(charid, 1);

		if (RuleB(World, AnnounceJoinQuits) == true) //this is having an issue, its not taking a true false swap, only takes default.
		{
			zoneserver_list.SendEmoteMessage(0, 0, 0, 15, "%s is logging on!", GetCharName());
			clog(WORLD__CLIENT_ERR, "Character is logging on: %s", GetCharName());
		}
	}
	else{
		uint32 groupid=database.GetGroupID(char_name);
		if(groupid>0){
			char* leader=0;
			char leaderbuf[64]={0};
			if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){
				EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
				GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
				gj->action=8;
				strcpy(gj->yourname,char_name);
				strcpy(gj->membername,leader);
				QueuePacket(outapp3);
				safe_delete(outapp3);
			}
		}
	}

	outapp = new EQApplicationPacket(OP_MOTD);
	char tmp[500] = {0};
	if (database.GetVariable("MOTD", tmp, 500)) {
		outapp->size = strlen(tmp)+1;
		outapp->pBuffer = new uchar[outapp->size];
		memset(outapp->pBuffer,0,outapp->size);
		strcpy((char*)outapp->pBuffer, tmp);

	} else {
		// Null Message of the Day. :)
		outapp->size = 1;
		outapp->pBuffer = new uchar[outapp->size];
		outapp->pBuffer[0] = 0;
	}
	QueuePacket(outapp);
	safe_delete(outapp);

	int MailKey = MakeRandomInt(1, INT_MAX);

	database.SetMailKey(charid, GetIP(), MailKey);

	char ConnectionType;

	ConnectionType = 'C';

	EQApplicationPacket *outapp2 = new EQApplicationPacket(OP_SetChatServer);
	char buffer[112];

	const WorldConfig *Config = WorldConfig::get();

	sprintf(buffer,"%s,%i,%s.%s,%c%08X",
		Config->ChatHost.c_str(),
		Config->ChatPort,
		Config->ShortName.c_str(),
		this->GetCharName(), ConnectionType, MailKey
	);
	outapp2->size=strlen(buffer)+1;
	outapp2->pBuffer = new uchar[outapp2->size];
	memcpy(outapp2->pBuffer,buffer,outapp2->size);
	QueuePacket(outapp2);
	safe_delete(outapp2);

	EnterWorld();

	return true;
}
Example #29
0
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
	// creates up to a 10 char name
	char vowels[18]="aeiouyaeiouaeioe";
	char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd";
	char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
	char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr";
	int rndnum=MakeRandomInt(0, 75),n=1;
	bool dlc=false;
	bool vwl=false;
	bool dbl=false;
	if (rndnum>63)
	{	// rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel
		rndnum=(rndnum-61)*2;	// name can't start with "ng" "nd" or "rk"
		rndname[0]=paircons[rndnum];
		rndname[1]=paircons[rndnum+1];
		n=2;
	}
	else if (rndnum>16)
	{
		rndnum-=17;
		rndname[0]=cons[rndnum];
	}
	else
	{
		rndname[0]=vowels[rndnum];
		vwl=true;
	}
	int namlen=MakeRandomInt(5, 10);
	for (int i=n;i<namlen;i++)
	{
		dlc=false;
		if (vwl)	//last char was a vowel
		{			// so pick a cons or cons pair
			rndnum=MakeRandomInt(0, 62);
			if (rndnum>46)
			{	// pick a cons pair
				if (i>namlen-3)	// last 2 chars in name?
				{	// name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng"
					rndnum=MakeRandomInt(0, 7)*2;
				}
				else
				{	// pick any from the set
					rndnum=(rndnum-47)*2;
				}
				rndname[i]=paircons[rndnum];
				rndname[i+1]=paircons[rndnum+1];
				dlc=true;	// flag keeps second letter from being doubled below
				i+=1;
			}
			else
			{	// select a single cons
				rndname[i]=cons[rndnum];
			}
		}
		else
		{		// select a vowel
			rndname[i]=vowels[MakeRandomInt(0, 16)];
		}
		vwl=!vwl;
		if (!dbl && !dlc)
		{	// one chance at double letters in name
			if (!MakeRandomInt(0, i+9))	// chances decrease towards end of name
			{
				rndname[i+1]=rndname[i];
				dbl=true;
				i+=1;
			}
		}
	}

	rndname[0]=toupper(rndname[0]);
	NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
	memset(ngs->name,0,64);
	strcpy(ngs->name,rndname);

	QueuePacket(app);
	return true;
}
Example #30
0
void Trap::Trigger(Mob* trigger)
{
	int i = 0;
	const NPCType* tmp = 0;
	switch (effect)
	{
		case trapTypeDebuff:
			if(message.empty())
			{
				entity_list.MessageClose(trigger,false,100,13,"%s triggers a trap!",trigger->GetName());
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
			}
			if(hiddenTrigger){
				hiddenTrigger->SpellFinished(effectvalue, trigger, 10, 0, -1, spells[effectvalue].ResistDiff);
			}
			break;
		case trapTypeAlarm:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,effectvalue,13,"A loud alarm rings out through the air...");
			}
			else
			{
				entity_list.MessageClose(trigger,false,effectvalue,13,"%s",message.c_str());
			}

			entity_list.SendAlarm(this,trigger,effectvalue);
			break;
		case trapTypeMysticSpawn:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,13,"The air shimmers...");
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
			}

			for (i = 0; i < effectvalue2; i++)
			{
				if ((tmp = database.GetNPCType(effectvalue)))
				{
					NPC* new_npc = new NPC(tmp, 0, x-5+MakeRandomInt(0, 10), y-5+MakeRandomInt(0, 10), z-5+MakeRandomInt(0, 10), MakeRandomInt(0, 249), FlyMode3);
					new_npc->AddLootTable();
					entity_list.AddNPC(new_npc);
					new_npc->AddToHateList(trigger,1);
				}
			}
			break;
		case trapTypeBanditSpawn:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,13,"A bandit leaps out from behind a tree!");
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
			}

			for (i = 0; i < effectvalue2; i++)
			{
				if ((tmp = database.GetNPCType(effectvalue)))
				{
					NPC* new_npc = new NPC(tmp, 0, x-2+MakeRandomInt(0, 5), y-2+MakeRandomInt(0, 5), z-2+MakeRandomInt(0, 5), MakeRandomInt(0, 249), FlyMode3);
					new_npc->AddLootTable();
					entity_list.AddNPC(new_npc);
					new_npc->AddToHateList(trigger,1);
				}
			}
			break;
		case trapTypeDamage:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,13,"%s triggers a trap!",trigger->GetName());
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
			}
			if(trigger->IsClient())
			{
				EQApplicationPacket* outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
				CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
				int dmg = MakeRandomInt(effectvalue, effectvalue2);
				trigger->SetHP(trigger->GetHP() - dmg);
				a->damage = dmg;
				a->sequence = MakeRandomInt(0, 1234567);
				a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
				a->spellid = 0;
				a->target = trigger->GetID();
				a->type = 253;
				trigger->CastToClient()->QueuePacket(outapp);
				safe_delete(outapp);
			}
	}
	respawn_timer.Start((respawn_time + MakeRandomInt(0, respawn_var)) * 1000);
	chkarea_timer.Disable();
	disarmed = true;
}