www.pudn.com > wow.rar > Character.cpp


// Copyright (C) 2004 Team Python
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "Character.h"
#include "UpdateMask.h"
#include "NetworkInterface.h"
#include "Quest.h"
#include "Opcodes.h"
#include "WorldServer.h"
#include "Timer.h" 
#include "math.h"

#define world WorldServer::getSingleton()

Character::Character ( ): Unit()
{ 
    m_objectType |= TYPE_PLAYER;
    m_objectTypeId = 4;
    m_afk = 0;
    m_curTarget[ 0 ] = m_curTarget[ 1 ] = 0;
    m_curSelection[ 0 ] = m_curSelection[ 1 ] = 0;
    m_updateValues[ OBJECT_FIELD_TYPE ] = m_objectType;
    m_lootGuid[1] = 0;
    m_lootGuid[0] = 0;
	memset(m_guildname, 0, 22);
    m_guildId = 0;
    m_petInfoId = 0;
    m_petLevel = 0;
    m_petFamilyId = 0;

    m_regenTimer = 0;
    m_attackTimer = 0;

	m_healingDuration = m_healingTimer = 0;
	m_replenish_field = 0;
	m_replenish_value = 0;

    memset(m_items, 0, 8*39);

    // Init inventory slots...should they be set to 0?  Better than not initializing them at all I guess
    for (int i = 0; i < 20; i++) {
        m_inventory[i].displayId = 0;
        m_inventory[i].itemType = 0;
    }

    m_lastHpRegen = 0;
    m_lastManaRegen = 0; 
 
	m_corpseDelay = 10000; 
    m_respawnDelay = 40000; 
 
	m_stat0=0; 
	m_stat1=0; 
	m_stat2=0; 
	m_stat3=0; 
	m_stat4=0; 
	stat0=0; 
	stat1=0; 
	stat2=0; 
	stat3=0; 
	stat4=0; 
	 
	uint32 m_health=0; 
	uint32 m_mana=0;
	m_timeToSave = 0;
	m_lastSavedTime = 0;

}


Character::~Character ( ) 
{ 

}


//====================================================================
//	Create
//	params: p_newChar
//	desc:	data form client to create a new character
//====================================================================
void Character::Create( uint32 guidlow, wowWData& data )//( uint8 * data, uint16 length )
{
    int i=0;
    uint8 race,class_,gender,skin,face,hairStyle,hairColor,facialHair,outfitId;
    uint16 displayId=0;
    uint32 baseattacktime[2];

    // Stats
    uint32 rage=0;

    Unit::Create(guidlow);
    m_guid[1] = 0;

    for (i = 0; i < 39; i++) {
        m_items[i].guid = 0;
        m_items[i].itemid = 0;
    }

    // unpack data into member variables
    data >> (char *)m_name;
    data >> race >> class_ >> gender >> skin >> face;
    data >> hairStyle >> hairColor >> facialHair >> outfitId;

    //////////  Constant for everyone  ////////////////
    /* Starting Locs
    Human: 0, -8949.95, -132.493, 83.5312
    Orc: 1, -618.518, -4251.67, 38.718
    Dwarf: 0, -6240.32, 331.033, 382.758
    Night Elf: 1, 10311.3, 832.463, 1326.41
    Undead: 0, 1676.35, 1677.45, 121.67
    Tauren: 1, -2917.58, -257.98, 52.9968
    Gnome: See Dwarf
    Troll: See Orc
    */
    baseattacktime[0] = 2000;
    baseattacktime[1] = 2000;

	// While
		m_mapId = 0;
        m_zoneId = 12;
        m_positionX = -8913.84f;
        m_positionY = -135.486f;
        m_positionZ = 80.4552f;
        m_stat0 = 20;
        m_stat1 = 20;
        m_stat2 = 20;
        m_stat3 = 20;
        m_stat4 = 20;
	// End

	if (race == 1)  // Human
    {
        /*m_mapId = 0;
        m_zoneId = 12;
        m_positionX = -8913.84f;
        m_positionY = -135.486f;
        m_positionZ = 80.4552f;
        m_stat0 = 20;
        m_stat1 = 20;
        m_stat2 = 20;
        m_stat3 = 20;
        m_stat4 = 20;*/
        displayId = 49 + gender;
    }
    else if (race == 2) // orc
    {
        /*m_mapId = 1;
        m_zoneId = 14;
        m_positionX = -618.518f;
        m_positionY = -4251.67f;
        m_positionZ = 38.718f;
        m_stat0 = 23;
        m_stat1 = 17;
        m_stat2 = 22;
        m_stat3 = 17;
        m_stat4 = 21;*/
        displayId = 51 + gender;
    }
    else if (race == 3) // dwarf
    {
        /*m_mapId = 0;
        m_zoneId = 1;
        m_positionX = -6240.32f;
        m_positionY = 331.033f;
        m_positionZ = 382.758f;
        m_stat0 = 22;
        m_stat1 = 17;
        m_stat2 = 23;
        m_stat3 = 19;
        m_stat4 = 19;*/
        displayId = 53 + gender;
    }
    else if (race == 4) // night elf
    {
        /*m_mapId = 1;
        m_zoneId = 141;
        m_positionX = 10311.3f;
        m_positionY = 832.463f;
        m_positionZ = 1326.41f;
        m_stat0 = 16;
        m_stat1 = 25;
        m_stat2 = 19;
        m_stat3 = 20;
        m_stat4 = 20;*/
        displayId = 55 + gender;
    }
    else if (race == 5) // undead
    {
        /*m_mapId = 0;
        m_zoneId = 85;
        m_positionX = 1676.35f;
        m_positionY = 1677.45f;
        m_positionZ = 121.67f;
        m_stat0 = 19;
        m_stat1 = 18;
        m_stat2 = 21;
        m_stat3 = 17;
        m_stat4 = 25;*/
        displayId = 57 + gender;
    }
    else if (race == 6) // tauren
    {
        /*m_mapId = 1;
        m_zoneId = 215;
        m_positionX = -2917.58f;
        m_positionY = -257.98f;
        m_positionZ = 52.9968f;
        m_stat0 = 25;
        m_stat1 = 16;
        m_stat2 = 22;
        m_stat3 = 16;
        m_stat4 = 21;*/
        displayId = 59 + gender;
    }   
    else if (race == 7) // gnome
    {
        /*m_mapId = 0;
        m_zoneId = 1;
        m_positionX = -6240.32f;
        m_positionY = 331.033f;
        m_positionZ = 382.758f;
        m_stat0 = 15;
        m_stat1 = 23;
        m_stat2 = 19;
        m_stat3 = 23;
        m_stat4 = 20;*/
        displayId = 1563 + gender;
    }
    else if (race == 8)     // troll
    {
        /*m_mapId = 1;
        m_zoneId = 14;
        m_positionX = -618.518f;
        m_positionY = -4251.67f;
        m_positionZ = 38.718f;
        m_stat0 = 20;
        m_stat1 = 22;
        m_stat2 = 21;
        m_stat3 = 16;
        m_stat4 = 21;*/
        displayId = 1478 + gender;
    }

/*
LEFT SIDE
Head		0
Neck		1
Shoulders	2
Back		14
Chest		4
Shirt		3
Tabard		18
Wrists		8

RIGHT SIDE
Hands		9
Waist		5
Legs		6
Feet		7
Finger A	10
Finger B	11
Trinket A	12
Trinket B	13

WIELDED
Main hand	15
Offhand		16
Ranged		17
/**/

// slot 19 is invalid.

    // Adjust stats and items based on class
    // Starting stats from: http://wowvault.ign.com/?dir=characters&content=stats
    // Starting items from: www.gotwow.net -- M!lksJake
    if (class_ == WARRIOR)    // warrior
    {
        //abilities
        addSpell(0x19CB, 0);   //attack
        //addSpell(2457, 0);     //battle stance
        //addSpell(107, 0);      //block
        //addSpell(78, 0);       //Strike (Rank 1)
        //addSpell(81, 0);       //dodge

	    world.m_hiItemGuid++;	 
        
        if (race == 1) // Human
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 60;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);      // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);      // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);      // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);   // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);     // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);   // Darnassian Bleu
        }
        else if (race == 2) // Orc
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 80;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);      // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);      // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);      // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);   // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);     // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);    // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
        else if (race == 3) // Dwarf
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 90;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);       // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);       // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);       // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);    // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);      // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
        else if (race == 4) // Night Elf
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 50;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 6120);     // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);       // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);       // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);    // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);      // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
        else if (race == 5) // Undead
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 70;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);       // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);       // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);       // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);    // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);      // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
        }
        else if (race == 6) // Tauren
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 80;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);      // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);      // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);      // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);   // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);     // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);    // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);   // tough hunk of bread
        }
        else if (race == 7) // Gnome
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 50;
			rage        = 35;;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);      // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);      // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);      // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);   // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);     // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);    // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);   // tough hunk of bread
        }
        else if (race == 8) // Troll
        {
			// +3 strength
			// +2 Stamina
			m_stat0 += 3;
			m_stat2 += 2;

			m_health      = 70;
			rage        = 35;
			//POWER TYPE: USES RAGE

			AddItemToSlot(3, world.m_hiItemGuid++, 38);      // recruit's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 39);      // recruit's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 40);      // recruit's boots
			AddItemToSlot(16, world.m_hiItemGuid++, 2362);   // worn wooden shield
			AddItemToSlot(15, world.m_hiItemGuid++, 25);     // worn short sword
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);    // tough jerky
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);   // tough hunk of bread
        }
    }
    else if (class_ == PALADIN)   // Paladin
    {
        //spells
        addSpell(679, 1);     //holy strike
        addSpell(635, 2);     //holy light
        //abilities
        addSpell(0x19CB, 0);  //attack
        //addSpell(107, 0);     //block
        //addSpell(81, 0);      //dodge

        world.m_hiItemGuid++;	

        if (race == 1) // Human
        {
			// +2 Strenght
			// +2 Stamina
			// +1 Spirit
			m_stat0 += 2;
			m_stat2 += 2;
			m_stat4 += 1;

			m_health      = 58;
			m_mana        = 84;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES MANA

			AddItemToSlot(3, world.m_hiItemGuid++, 45);       // squire's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 44);       // squire's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 43);       // squire's boots
			AddItemToSlot(15, world.m_hiItemGuid++, 2361);    // battleworn hammer
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
        }
        else if (race == 3) // Dwarfs
        {
			// +2 Strenght
			// +2 Stamina
			// +1 Spirit
			m_stat0 += 2;
			m_stat2 += 2;
			m_stat4 += 1;
        
			m_health      = 85;
			m_mana        = 83;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES MANA

			AddItemToSlot(3, world.m_hiItemGuid++, 45);       // squire's shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 44);       // squire's pants
			AddItemToSlot(7, world.m_hiItemGuid++, 43);       // squire's boots
			AddItemToSlot(15, world.m_hiItemGuid++, 2361);    // battleworn hammer
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
    }
    else if (class_ == HUNTER)   // Hunter
    {
        m_health      = 95;
        m_mana        = 0;

	    world.m_hiItemGuid++;	    
	    AddItemToSlot(3, world.m_hiItemGuid++, 38);       // recruit's shirt
        AddItemToSlot(6, world.m_hiItemGuid++, 39);       // recruit's pants
        AddItemToSlot(7, world.m_hiItemGuid++, 40);       // recruit's boots
        AddItemToSlot(16, world.m_hiItemGuid++, 2362);    // worn shield
        AddItemToSlot(15, world.m_hiItemGuid++, 2488);    // footman sword
        //AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
        //AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread

    }
    else if (class_ == ROGUE)   // Rogue
    {
        //abilities
        addSpell(0x19CB, 0); //attack
        //addSpell(1752, 1);      //sinister strike
       // addSpell(2764, 2);      //throw
        //addSpell(2098, 0);      //eviscrate
        //addSpell(81, 0);        //dodge
        
	    world.m_hiItemGuid++;	    

        if (race == 1) // Human
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 56;
			rage        = 84;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
        }
        else if (race == 2) // Orc
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 72;
			rage        = 83;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
        }
        else if (race == 3) // Dwarf
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 80;
			rage        = 84;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
        else if (race == 4) // Night Elf
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 48;
			rage        = 83;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
        }
        else if (race == 5) // Undead
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 64;
			rage        = 83;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: USES ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
        }
        else if (race == 7) // Gnome
        {
			// +2 Strenght
			m_stat0 += 2;
        
			m_health      = 48;
			rage        = 84;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
			//POWER TYPE: ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
			AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
			AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
        }
        else if (race == 8) // Troll
        {
			// +2 Strenght
			m_stat0 += 2;

			m_health      = 64;
			rage        = 83;
			baseattacktime[0] = 2900;
			baseattacktime[1] = 2000;
        //POWER TYPE: USES ENERGY

			AddItemToSlot(3, world.m_hiItemGuid++, 49);       // Footpad’s shirt
	        AddItemToSlot(6, world.m_hiItemGuid++, 48);       // Footpad’s Pants
	        AddItemToSlot(7, world.m_hiItemGuid++, 47);       // Footpad’s shoes
		    AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // Worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
        }

    }
    else if (class_ == PRIEST)   // Priest
    {
        //spells
        addSpell(585, 1); // holy smite 
        addSpell(2050, 2);       // lesser heal
        //abilities
        addSpell(0x19CB, 0); //attack
        //addSpell(5019, 0);       // shoot wands
        //addSpell(81, 0);         //dodge
        

        if (race == 1) // Human
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;

			m_health      = 52;
			m_mana        = 150;
			//POWER TYPE: USES MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 51);       // neophytes's boots
			AddItemToSlot(6, world.m_hiItemGuid++, 52);       // neophytes's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6098);     // neophyte's robe
			AddItemToSlot(3, world.m_hiItemGuid++, 53);       // neophyte's shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 8) // Troll
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;

			m_health      = 58;
			m_mana        = 128;
			//POWER TYPE: USES MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 51);       // neophytes's boots
			AddItemToSlot(6, world.m_hiItemGuid++, 52);       // neophytes's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6144);     // neophyte's robe
			AddItemToSlot(3, world.m_hiItemGuid++, 53);       // neophyte's shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 3) // Dwarf
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;

			m_health      = 76;
			m_mana        = 130;
			//POWER TYPE: USES MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 51);       // neophytes's boots
			AddItemToSlot(6, world.m_hiItemGuid++, 52);       // neophytes's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6098);     // neophyte's robe
			AddItemToSlot(3, world.m_hiItemGuid++, 53);       // neophyte's shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 4) // Night Elf
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;

			m_health      = 45;
			m_mana        = 160;
			//POWER TYPE: USES MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 51);       // neophytes's boots
			AddItemToSlot(6, world.m_hiItemGuid++, 52);       // neophytes's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6098);     // neophyte's robe
			AddItemToSlot(3, world.m_hiItemGuid++, 53);       // neophyte's shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 5) // Undead
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;

			m_health      = 58;
			m_mana        = 129;
			//POWER TYPE: USES MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 51);       // neophytes's boots
			AddItemToSlot(6, world.m_hiItemGuid++, 52);       // neophytes's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6144);     // neophyte's robe
			AddItemToSlot(3, world.m_hiItemGuid++, 53);       // neophyte's shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
        }
    }
    else if (class_ == SHAMAN)   // Shaman
    {
        //spells
        addSpell(403, 1);       // lightning bolt
        addSpell(331, 2);       // healing wave
        //abilities
        addSpell(0x19CB, 0);    //attack
        //addSpell(81, 0);        //dodge
        //addSpell(107, 0);       //block


	    world.m_hiItemGuid++;

        if (race == 2) // Orc
        {
			// +1 Strenght
			// +1 Stamina
			// +2 Intellect
			// +1 Spirit
			m_stat0 += 1;
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 1;

			m_health      = 72;
			m_mana        = 68;
			//POWER TYPE: MANA

//			AddItemToSlot(4, world.m_hiItemGuid++, 154);      // primitive mantel
//			AddItemToSlot(3, world.m_hiItemGuid++, 153);      // primitive kilt
            AddItemToSlot(4, world.m_hiItemGuid++, 6119);     // neophyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 6) // Tauren
        {
			// +1 Strenght
			// +1 Stamina
			// +2 Intellect
			// +1 Spirit
			m_stat0 += 1;
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 1;

			m_health      = 72;
			m_mana        = 67;
			//POWER TYPE: MANA

//			AddItemToSlot(4, world.m_hiItemGuid++, 154);      // primitive mantel
//			AddItemToSlot(3, world.m_hiItemGuid++, 153);      // primitive kilt
            AddItemToSlot(4, world.m_hiItemGuid++, 6119);     // neophyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 36);      // worn mace
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
		}
        else if (race == 8) // Troll
		{
			// +1 Strenght
			// +1 Stamina
			// +2 Intellect
			// +1 Spirit
			m_stat0 += 1;
			m_stat2 += 1;
			m_stat3 += 2; 
			m_stat4 += 1;
        
			m_health      = 64;
			m_mana        = 67;
			//POWER TYPE: MANA

			AddItemToSlot(4, world.m_hiItemGuid++, 154);      // primitive mantel
			AddItemToSlot(3, world.m_hiItemGuid++, 153);      // primitive kilt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
    }
    else if (class_ == MAGE)   // mage
    {
        //spells
        addSpell(0x0085, 1);    // firebolt
        //addSpell(168, 2);       // frost armor
        //abilities
        addSpell(0x19CB, 0);    //attack
        //addSpell(5019, 0);      //shoot wand
        //addSpell(81, 0);        //dodge


	    world.m_hiItemGuid++;	

        if (race == 1) //human
        {
			// +2 Intellect
			// +3 Spirit
			m_stat3 += 2;
			m_stat4 += 3;
          
			m_health      = 52;
			m_mana        = 150;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 55);       // Apprentice’s Boots
			AddItemToSlot(6, world.m_hiItemGuid++, 1395);     // Apprentice’s Pants
			AddItemToSlot(4, world.m_hiItemGuid++, 56);       // Apprentice’s Robe
			AddItemToSlot(3, world.m_hiItemGuid++, 6096);     // Apprentice’s Shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 8) // Troll
        {
			// +2 Intellect
			// +3 Spirit
			m_stat3 += 2;
			m_stat4 += 3;
         
			m_health      = 58;
			m_mana        = 128;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 55);       // Apprentice’s Boots
			AddItemToSlot(6, world.m_hiItemGuid++, 1395);     // Apprentice’s Pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6140);     // Apprentice’s Robe
			AddItemToSlot(3, world.m_hiItemGuid++, 6096);     // Apprentice’s Shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 3) // Dwarf
        {
			// +2 Intellect
			// +3 Spirit
			m_stat3 += 2;
			m_stat4 += 3;
         
			m_health      = 70;
			m_mana        = 140;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 55);       // Apprentice’s Boots
			AddItemToSlot(6, world.m_hiItemGuid++, 1395);     // Apprentice’s Pants
			AddItemToSlot(4, world.m_hiItemGuid++, 56);       // Apprentice’s Robe
			AddItemToSlot(3, world.m_hiItemGuid++, 6096);     // Apprentice’s Shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 5) // Undead
        {
			// +2 Intellect
			// +3 Spirit
			m_stat3 += 2;
			m_stat4 += 3;
         
			m_health      = 58;
			m_mana        = 129;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 55);       // Apprentice’s Boots
			AddItemToSlot(6, world.m_hiItemGuid++, 1395);     // Apprentice’s Pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6140);     // Apprentice’s Robe
			AddItemToSlot(3, world.m_hiItemGuid++, 6096);     // Apprentice’s Shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
        }
        else if (race == 7) // Gnome
        {
			// +2 Intellect
			// +3 Spirit
			m_stat3 += 2;
			m_stat4 += 3;
         
			m_health      = 51;
			m_mana        = 180;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 55);       // Apprentice’s Boots
			AddItemToSlot(6, world.m_hiItemGuid++, 1395);     // Apprentice’s Pants
			AddItemToSlot(4, world.m_hiItemGuid++, 56);       // Apprentice’s Robe
			AddItemToSlot(3, world.m_hiItemGuid++, 6096);     // Apprentice’s Shirt
			AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
        }
    }
    else if (class_ == WARLOCK)   // Warlock
    {
        //spells
        addSpell(686, 1);      //shadow bolt
        //addSpell(687, 2);      //demon skin
        //abilities
        addSpell(0x19CB, 0);   //attack
        //addSpell(5019, 0);     // shoot wands
        //addSpell(81, 0);       //dodge

	    world.m_hiItemGuid++;	

        if (race == 1) //human
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;
        
			m_health      = 54;
			m_mana        = 130;
			baseattacktime[0] = 1600;
			baseattacktime[1] = 2000;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 59);       // acolyte's shoes
			AddItemToSlot(6, world.m_hiItemGuid++, 1396);     // acolyte's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 57);       // acolyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(25, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 2070);    // Darnassian Bleu
        }
        else if (race == 2) // Orc
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;
        
			m_health      = 68;
			m_mana        = 109;
			baseattacktime[0] = 1600;
			baseattacktime[1] = 2000;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 59);       // acolyte's shoes
			AddItemToSlot(6, world.m_hiItemGuid++, 1396);     // acolyte's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6129);     // acolyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(25, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 7) // Gnome
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;
        
			m_health      = 47;
			m_mana        = 160;
			baseattacktime[0] = 1600;
			baseattacktime[1] = 2000;
			//POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 59);       // acolyte's shoes
			AddItemToSlot(6, world.m_hiItemGuid++, 1396);     // acolyte's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 57);       // acolyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);    // tough hunk of bread
			//AddItemToSlot(25, world.m_hiItemGuid++, 159);     // refreshing spring water
        }
        else if (race == 5) // Undead
        {
			// +1 Stamina
			// +2 Intellect
			// +2 Spirit
			m_stat2 += 1;
			m_stat3 += 2;
			m_stat4 += 2;
        
			m_health      = 61;
			m_mana        = 109;
			baseattacktime[0] = 1600;
			baseattacktime[1] = 2000;
        //POWER TYPE: MANA

			AddItemToSlot(7, world.m_hiItemGuid++, 59);       // acolyte's shoes
			AddItemToSlot(6, world.m_hiItemGuid++, 1396);     // acolyte's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6129);     // acolyte's robe
			AddItemToSlot(15, world.m_hiItemGuid++, 2092);    // worn dagger
			//AddItemToSlot(23, world.m_hiItemGuid++, 117);     // tough jerky
			//AddItemToSlot(25, world.m_hiItemGuid++, 159);     // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4604);    // forest mushroom cap
        }	    
    }
    else if (class_ == DRUID)  // druid
    {
        //spells
        addSpell(5176, 1);    // wrath
        addSpell(5185, 2);    // healing touch
        //addSpell(1126, 1);    // Mark of the Wild
        //abilities
        addSpell(0x19CB, 0);  //attack
        //addSpell(81, 0);      //dodge

	    world.m_hiItemGuid++;	    
		AddItemToSlot(15, world.m_hiItemGuid++, 35);      // bent staff
     
        if (race == 4) // Night Elf
        {
			// +1 Strenght
			// +1 Stamina
			// +1 Agility
			// +1 Intellect
			// +1 Spirit
			m_stat0 += 1;
			m_stat1 += 1;
			m_stat2 += 1;
			m_stat3 += 1;
			m_stat4 += 1;
        
			m_health      = 46;
			m_mana        = 105;
			//POWER TYPE: MANA
			//NOTE: USES RAGE IN BEAR FORM

//			AddItemToSlot(6, world.m_hiItemGuid++, 6124);    // Novice's pants
			AddItemToSlot(4, world.m_hiItemGuid++, 6123);    // Novice's Robe
//			AddItemToSlot(15, world.m_hiItemGuid++, 3661);   // Hand crafted staff
/*			AddItemToSlot(24, world.m_hiItemGuid++, 159);    // Refreshing spring water
			AddItemToSlot(23, world.m_hiItemGuid++, 4540);   // Tough hunk of bread*/
        }
		else if (race == 6) // Tauren
        {
			// +1 Strenght
			// +1 Stamina
			// +1 Agility
			// +1 Intellect
			// +1 Spirit
			m_stat0 += 1;
			m_stat1 += 1;
			m_stat2 += 1;
			m_stat3 += 1;
			m_stat4 += 1;
        
			m_health      = 68;
			m_mana        = 84;
			//POWER TYPE: MANA
			//NOTE: USES RAGE IN BEAR FORM

//			AddItemToSlot(6, world.m_hiItemGuid++, 6124);    // Novice's pants
//			AddItemToSlot(4, world.m_hiItemGuid++, 6139);    // Novice's Robe
//			AddItemToSlot(15, world.m_hiItemGuid++, 3661);   // bent staff
            AddItemToSlot(4, world.m_hiItemGuid++, 6119);     // neophyte's robe
			//AddItemToSlot(24, world.m_hiItemGuid++, 159);    // refreshing spring water
			//AddItemToSlot(23, world.m_hiItemGuid++, 4540);   // tough hunk of bread
        }     
    }
	
    // Set Starting stats for char
    setUpdateMaskBit(OBJECT_FIELD_GUID);          
    setUpdateMaskBit(OBJECT_FIELD_TYPE);
    setUpdateFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);         
    setUpdateValue(OBJECT_FIELD_PADDING, 0xeeeeeeee);        
    setUpdateValue(UNIT_FIELD_HEALTH, m_health);   
	if (rage)
		setUpdateValue(UNIT_FIELD_POWER1, 0 );        
	else
		setUpdateValue(UNIT_FIELD_POWER1, m_mana );        
    setUpdateValue(UNIT_FIELD_POWER2, 1000 );
    setUpdateValue(UNIT_FIELD_POWER3, 10 );        
    setUpdateValue(UNIT_FIELD_POWER4, 100 );
    setUpdateValue(UNIT_FIELD_POWER5, 0xeeeeeeee );        
    setUpdateValue(UNIT_FIELD_MAXHEALTH, m_health);
	if (rage)
	    setUpdateValue(UNIT_FIELD_MAXPOWER1, 0 );
	else
		setUpdateValue(UNIT_FIELD_MAXPOWER1, m_mana );
    setUpdateValue(UNIT_FIELD_MAXPOWER2, 1000 );
    setUpdateValue(UNIT_FIELD_MAXPOWER3, 10 );        
    setUpdateValue(UNIT_FIELD_MAXPOWER4, 100 );
    setUpdateValue(UNIT_FIELD_LEVEL, 1 );            
    setUpdateValue(UNIT_FIELD_FACTIONTEMPLATE, 1 );
    setUpdateValue(UNIT_FIELD_BYTES_0, ( race ) + ( class_ << 8 ) + ( gender << 16 ) );          
    setUpdateValue(UNIT_FIELD_STAT0, m_stat0 );
    setUpdateValue(UNIT_FIELD_STAT1, m_stat1 );
    setUpdateValue(UNIT_FIELD_STAT2, m_stat2 );
    setUpdateValue(UNIT_FIELD_STAT3, m_stat3 );
    setUpdateValue(UNIT_FIELD_STAT4, m_stat4 );
	setUpdateValue(PLAYER_FIELD_POSSTAT0, 0  );        
    setUpdateValue(PLAYER_FIELD_POSSTAT1, 0 );
    setUpdateValue(PLAYER_FIELD_POSSTAT2, 0 );        
    setUpdateValue(PLAYER_FIELD_POSSTAT3, 0 );
    setUpdateValue(PLAYER_FIELD_POSSTAT4, 0 );        
    setUpdateValue(PLAYER_FIELD_NEGSTAT0, 0 );        
    setUpdateValue(PLAYER_FIELD_NEGSTAT1, 0 );
    setUpdateValue(PLAYER_FIELD_NEGSTAT2, 0 );        
    setUpdateValue(PLAYER_FIELD_NEGSTAT3, 0 );
    setUpdateValue(PLAYER_FIELD_NEGSTAT4, 0 );        
    setUpdateValue(PLAYER_FIELD_COINAGE, 0  );
    setUpdateValue(UNIT_FIELD_BASEATTACKTIME, baseattacktime[0] );   
    setUpdateValue(UNIT_FIELD_BASEATTACKTIME+1, baseattacktime[1]  );
    setUpdateFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.388999998569489f );  
    setUpdateFloatValue(UNIT_FIELD_COMBATREACH, 1.5f   );
    setUpdateValue(UNIT_FIELD_DISPLAYID, displayId  );      
	setUpdateValue(UNIT_FIELD_NATIVEDISPLAYID, displayId );  
    setUpdateValue(UNIT_FIELD_FLAGS, 0x00000008 );
    setUpdateValue(PLAYER_BYTES, ((uint32)skin) | ((uint32)face << 8) | ((uint32)hairStyle << 16) | (hairColor << 24));
    setUpdateValue(PLAYER_BYTES_2, (facialHair << 8) + (01 << 24) );
    setUpdateValue(PLAYER_XP, 0 );                 
    setUpdateValue(PLAYER_NEXT_LEVEL_XP, 400);
    setUpdateValue(PLAYER_REST_STATE_EXPERIENCE, 0 );
    setUpdateValue(PLAYER_CHARACTER_POINTS1, 0);
    setUpdateValue(UNIT_FIELD_AURALEVELS , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 1 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 2 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 3 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 4 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 5 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 6 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 7 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 8 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURALEVELS + 9 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 1 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 2 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 3 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 4 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 5 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 6 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 7 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 8 , 0xeeeeeeee);
    setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + 9 , 0xeeeeeeee);

	updateItemStats();

	// Init inventory slots...should they be set to 0?  Better than not initializing them at all I guess
    for (i = 0; i < 20; i++) {
        m_inventory[i].displayId = 0;
        m_inventory[i].itemType = 0;
    }

    // Not worrying about this stuff for now
    m_guildId = 0;
    m_petInfoId = 0;
    m_petLevel = 0;
    m_petFamilyId = 0;
}


void Character::Update( uint32 p_time )
{
    if(m_regenTimer > 0)
    {
        if(p_time >= m_regenTimer)
            m_regenTimer = 0;
        else
            m_regenTimer -= p_time;
    }

    if(m_attackTimer > 0)
    {
        if(p_time >= m_attackTimer)
            m_attackTimer = 0;
        else
            m_attackTimer -= p_time;
    }

    if (m_state & UF_ATTACKING)
    {
        // In combat!
        if (isAttackReady())
        {
            Unit *pVictim = NULL;
            if (m_curSelection[1] == uint32(0)) 
            {   // player guid
                // player vs player not implemented

                // !! Bah, previously spawned creatures have guid[1] of 0
                if (world.mCreatures.find(m_curSelection[0]) != world.mCreatures.end()){
                    pVictim = world.mCreatures[m_curSelection[0]];
                }
            } 
            else if (m_curSelection[1] == 0xF0001000 || m_curSelection[1] == 0xF0003000)
            {   // monster
                if (world.mCreatures.find(m_curSelection[0]) != world.mCreatures.end()){
                    pVictim = world.mCreatures[m_curSelection[0]];
                }
            }

            if (!pVictim){
                printf("Character::Update:  No valid current selection to attack, stopping attack\n");
                clearStateFlag(UF_ATTACKING);
                world.mCombatHandler.smsg_AttackStop((Unit*)this, m_curSelection);
            }
            else
            {
                world.mCombatHandler.AttackerStateUpdate((Unit*)this, pVictim, 0);
                setAttackTimer();
            }
        }
    }
	//Hope it fixs the combat bug because if a attacker is out of range the attack will be
	//ignored and so any spells work because there is not creature id selection with mouse
	else if(m_state & !UF_ATTACKING)
	{
		if (isAttackReady())
        {
            Unit *pVictim = NULL;
            if (m_curSelection[1] == uint32(0)) 
            {   // player guid
                // player vs player not implemented

                // !! Bah, previously spawned creatures have guid[1] of 0
                if (world.mCreatures.find(m_curSelection[0]) != world.mCreatures.end()){
                    pVictim = world.mCreatures[m_curSelection[0]];
                }
            } 
            else if (m_curSelection[1] == 0xF0001000 || m_curSelection[1] == 0xF0003000)
            {   // monster
                if (world.mCreatures.find(m_curSelection[0]) != world.mCreatures.end()){
                    pVictim = world.mCreatures[m_curSelection[0]];
                }
            }

            if (!pVictim){
                printf("Character::Update:  No valid current selection to attack, stopping attack\n");
                clearStateFlag(UF_ATTACKING);
                world.mCombatHandler.smsg_AttackStop((Unit*)this, m_curSelection);
            }
			else
            {
                world.mCombatHandler.AttackerStateUpdate((Unit*)this, pVictim, 0);
                setAttackTimer();
            }
		}
	}
    // only regenerate if NOT in combat, and if alive
    if (isAlive() && !m_wport && !m_combat)
    {
        uint32 hp       = getUpdateValue(UNIT_FIELD_HEALTH);
        uint32 max_hp   = getUpdateValue(UNIT_FIELD_MAXHEALTH);

        uint32 mp       = getUpdateValue(UNIT_FIELD_POWER1);
        uint32 max_mp   = getUpdateValue(UNIT_FIELD_MAXPOWER1);

        // Regenerate health and mana if necessary
        hp = Regen(hp, max_hp, UNIT_FIELD_HEALTH, &m_lastHpRegen);
        mp = Regen(mp, max_mp, UNIT_FIELD_POWER1, &m_lastManaRegen);
    }
	else if (isAlive() && !m_wport && m_combat)
	{
		if  (getUpdateValue(UNIT_FIELD_MAXPOWER1) >0)
		{
		    uint32 mp       = getUpdateValue(UNIT_FIELD_POWER1);
	        uint32 max_mp   = getUpdateValue(UNIT_FIELD_MAXPOWER1);
	        mp = Regen(mp, max_mp, UNIT_FIELD_POWER1, &m_lastManaRegen);
		}
	}
	// nothin changes start
	else if(m_healingDuration > 0) 
	{
		if(m_healingTimer > 0)
		{
			if(p_time >= m_healingTimer)
				m_healingTimer = 0;
			else
				m_healingTimer -= p_time;
		}
		if(m_healingTimer == 0)
		{
			if( getUpdateValue( m_replenish_field ) == getUpdateValue( m_replenish_field+6 && m_replenish_field == 20) ) 
			{
				wowWData data;
				data.clear();	
  				data.Initialise( 5, SMSG_CAST_RESULT );
  				data << m_spell << uint8( 0x02);
				data << uint8( 17 );
  				pClient->SendMsg( &data );
				printf("OK print message: You are too full to eat");
				m_healingDuration = 0;
			} 
			else if( getUpdateValue( m_replenish_field ) == getUpdateValue( m_replenish_field+6 && m_replenish_field == 21) ) 
			{
				wowWData data;
				data.clear();	
  				data.Initialise( 5, SMSG_CAST_RESULT );
  				data << m_spell << uint8( 0x02);
				data << uint8( 17 );
  				pClient->SendMsg( &data );
				printf("OK print message: You can not drink any more yet");
				m_healingDuration = 0;
			} 
			else 
			{
				 m_healingDuration--;
				 m_healingTimer = 1000;
				 uint32 heal = getUpdateValue( m_replenish_field );
				 setUpdateValue( m_replenish_field, heal+m_replenish_value );
				 printf("Should heal here!\n");
			}
		}
	}
	/////////////////////////////////////////////////////////////////////
	////////////DAMAGE ABSORB TIMER - changed by nothin//////////////////
	if(m_absorbDuration > 0)
	{
		m_absorb = 1;
		if(m_absorbTimer > 0)
		{
			if(p_time >= m_absorbTimer)
				m_absorbTimer = 0;
			else
				m_absorbTimer -= p_time;
		}
		if(m_absorbTimer == 0)
		{
			m_absorbDuration--;
			m_absorbTimer = 1000;
			printf("Absorb Time: %u\n", m_absorbDuration);
		}
		if(m_absorbDuration == 0) 
		{
			m_absorb = 0;
			printf("OK absorb time is up for now :(\n");
		}
	}


	////////////Aura TIMER - changed by nothin/////////////////////////////
	if(m_auraDuration > 0)
	{
		if(m_auraTimer > 0)
		{
			if(p_time >= m_auraTimer)
				m_auraTimer = 0;
			else
				m_auraTimer -= p_time;
		}
		if(m_auraTimer == 0)
		{
			m_auraDuration--;
			m_auraTimer = 1000;
			printf("Aura Time: %u\n", m_auraDuration);
		}
		if(m_auraDuration == 0) 
		{
			setUpdateValue(UNIT_FIELD_AURALEVELS + m_aura_found, 0);
			setUpdateValue(UNIT_FIELD_AURAAPPLICATIONS + m_aura_found, 0);
			setUpdateValue(UNIT_FIELD_AURA + m_aura_found*4 + m_aura_found2, 0);
			printf("OK aura time is up for now Charhandler:(\n");
		}
	}
	///////////////////////////////////////////////////////////////////////

	////////////MANA SHIELD TIMER - changed by nothin//////////////////////
	if(m_shieldDuration > 0)
	{
		m_shield = 1;
		if(m_shieldTimer > 0)
		{
			if(p_time >= m_shieldTimer)
				m_shieldTimer = 0;
			else
				m_shieldTimer -= p_time;
		}
		if(m_shieldTimer == 0)
		{
			m_shieldDuration--;
			m_shieldTimer = 1000;
			printf("Shield Time: %u\n", m_shieldDuration);
		}
		if(m_shieldDuration == 0) 
		{
			m_shield = 0;
			printf("OK shield time is up for now :(\n");
		}
	}
	///////////////////////////////////////////////////////////////////////


	//START OF LINA DEATH FIX 
	if(m_deathState == JUST_DIED) 
	{ 
		setUpdateValue( PLAYER_BYTES_2, 0x10 | getUpdateValue( PLAYER_BYTES_2 ) ); 
		setUpdateValue( UNIT_FIELD_FLAGS, 65536 | getUpdateValue( UNIT_FIELD_FLAGS ) ); 
        setDeathState(CORPSE); 
 
		uint32 petGUID = getUpdateValue(UNIT_FIELD_SUMMON); 
 
		if( petGUID != 0) 
		{ 
			Unit* pet_caster = world.GetCreature(petGUID); 
			if(pet_caster) 
			{ 
				pet_caster->setDeathState(JUST_DIED); 
				pet_caster->m_corpseDelay = 10000; 
				pet_caster->m_respawnDelay = 30000; 
			} 
		} 
		printf("Placing corpse...\n"); 
	}/* 
	if(m_deathTimer > 0) 
    { 
        if(p_time >= m_deathTimer) 
            m_deathTimer = 0; 
        else 
            m_deathTimer -= p_time; 
 
        if (m_deathTimer <= 0) 
        { 
            m_respawnTimer = m_respawnDelay; 
			setDeathState(ALIVE); 
            printf("Removing corpse...\n"); 
        } 
    } 
    else if (m_respawnTimer > 0) 
    { 
        if(p_time >= m_respawnTimer) 
            m_respawnTimer = 0; 
        else 
            m_respawnTimer -= p_time; 
 
        if(m_respawnTimer <= 0) 
        { 
            UpdateMask mask; 
            wowWData data; 
            WorldServer::getSingletonPtr()->mObjectMgr.SetCreateUnitBits(mask); 
            uint32 max_health = getUpdateValue(UNIT_FIELD_MAXHEALTH); 
            setUpdateValue(UNIT_FIELD_HEALTH, max_health); 
 
			//maybe tale some xp away? 
			//pClient->getCurrentChar( )->setUpdateValue( UNIT_FIELD_FLAGS, 8 ); 
			setUpdateValue( UNIT_FIELD_FLAGS, (0xffffffff - 65536) & getUpdateValue( UNIT_FIELD_FLAGS ) ); 
			setUpdateValue( UNIT_FIELD_AURA +32, 0 ); 
			setUpdateValue( UNIT_FIELD_AURAFLAGS +4, 0 ); 
			setUpdateValue( UNIT_FIELD_AURASTATE, 0 ); 
			//pClient->getCurrentChar( )->setUpdateValue( PLAYER_BYTES_2, 16777984 ); 
			setUpdateValue( PLAYER_BYTES_2, (0xffffffff - 0x10) & pClient->getCurrentChar( )->getUpdateValue( PLAYER_BYTES_2 ) ); 
			//setDeathState(ALIVE); 
 
			uint8 buf[256]; 
 
			uint32 xp = getUpdateValue(PLAYER_XP); 
			uint32 xpt = (uint32)( 100 * getLevel() * pow(getLevel(),1.2)); 
			int32 newxp = xp - xpt; 
			if(newxp < 0)  
			{ 
				sprintf((char*)buf,"You lose all of youre XP, be carefull."); 
				setUpdateValue(PLAYER_XP, 0); 
			} 
			else  
			{ 
				sprintf((char*)buf,"You lose %u XP.", xpt); 
				setUpdateValue(PLAYER_XP, newxp); 
			} 
			WorldServer::getSingleton().mChatHandler.FillMessageData(&data, 0x09, pClient, buf); 
			pClient->SendMsg( &data ); 
			printf("Take XP %i, so %i\n", xpt, newxp); 
 
			uint32 money = getUpdateValue(PLAYER_FIELD_COINAGE); 
			uint32 moneyt = (uint32)(100 * pow(getLevel(),1.2)); 
			int32 newmoney = money - moneyt; 
			if(newmoney < 0)  
			{ 
				sprintf((char*)buf,"You lose all of youre coppers, be carefull."); 
				setUpdateValue(PLAYER_FIELD_COINAGE, 0); 
			} 
			else  
			{ 
				sprintf((char*)buf,"You lose %u coppers.", moneyt); 
				setUpdateValue(PLAYER_FIELD_COINAGE, newmoney); 
			} 
			WorldServer::getSingleton().mChatHandler.FillMessageData(&data, 0x09, pClient, buf); 
			pClient->SendMsg( &data ); 
			printf("Take Gold %i, so %i\n", moneyt, newmoney); 
 
            printf("Respawning...\n"); 
        } 
    } 
	//END OF LINA DEATH FIX*/
	//LeMMiNGS Auto Save each 5min
	if (m_timeToSave == 0) m_timeToSave = (uint32)time(NULL)+300;
	if ((uint32)time(NULL) > m_timeToSave) {
		m_timeToSave += 300;
		if  (pClient->IsInWorld()) {
			pClient->getDB()->setCharacter( pClient->getCurrentChar( ) );
			pClient->getCurrentChar()->setLastSavedTime((uint32)time(NULL));
			wowWData data;
			ChatHandler pChat; 
			pChat.FillMessageData(&data, 0x09, pClient, (uint8*)"Character auto-saved"); 
			pClient->SendMsg( &data );
		}
	}
	if (((uint32)time(NULL) > m_taxi) && m_taxi) { //taxi dismount on destination by LeMMiNGS
		m_taxi = 0;
	    pClient->getCurrentChar( )->setUpdateValue(UNIT_FIELD_MOUNTDISPLAYID , 0);
		pClient->getCurrentChar( )->removeUnitFlag( 0x003000 );
		pClient->getCurrentChar( )->removeUnitFlag( 0x000004 );
		world.CheckForInRangeObjects(pClient->getCurrentChar()); //fix for sometimes range objects not showing.. (havent tested so much .. was fixed?)
		wowWData data;
		float x, y, z;
        DatabaseInterface *dbi = Database::getSingleton( ).createDatabaseInterface( );
		dbi->getTaxiDest(m_taxinode, x, y, z);
        Database::getSingleton( ).removeDatabaseInterface( dbi );
		pClient->getCurrentChar()->TeleportAck(&data, x, y, z);
		pClient->SendMsg(&data);
	}
    UpdateObject();
}

// Regenerates the regenField's curValue to the maxValue
// Right now, everything regenerates at the same rate
// A possible mod is to add another parameter, the stat regeneration is based off of (Intelligence for mana, Strength for HP)
// And build a regen rate based on that
// LeMMiNGS: Check for /sleep and itemstats
uint32 Character::Regen(uint32 curValue, uint32 maxValue, uint16 regenField, uint32* lastRegen)
{
    if (curValue < maxValue)
    {
	    uint32 regenDelay = 6; //standing
		if ((uint32)getUpdateValue(UNIT_FIELD_BYTES_1) == 1) regenDelay = 3; //sitting
		else if ((uint32)getUpdateValue(UNIT_FIELD_BYTES_1) == 3) regenDelay = 1; //sleeping

        // Cheap mod by mstic :)
        // Changes hp/Mana regen to a percent of Stamina / Spirit currently 15%
		//Follower: Say it with me people "code,test,Have other people test, then commit.
        // check if it's time to regen health
        if ((uint32)time(NULL) > *lastRegen + regenDelay)
        {
            *lastRegen = (time(NULL));
			uint32 stamina, spirit;
			stamina = getUpdateValue(UNIT_FIELD_STAT2) + getUpdateValue(PLAYER_FIELD_POSSTAT2) - getUpdateValue(PLAYER_FIELD_NEGSTAT2);
			spirit = getUpdateValue(UNIT_FIELD_STAT4) + getUpdateValue(PLAYER_FIELD_POSSTAT4) - getUpdateValue(PLAYER_FIELD_NEGSTAT4);
            switch (regenField)
            {
			case UNIT_FIELD_HEALTH : curValue+=uint32(stamina*.15);
                break;
            case UNIT_FIELD_POWER1 : curValue+=uint32(spirit*.15);
                break;
            default : curValue = 0;
                break;
            }
		}
		if (curValue > maxValue) curValue = maxValue;
		if (curValue < 0) curValue = 0;
	}
	setUpdateValue(regenField, curValue);
	return curValue;
}

/*uint32 Character::Regen(uint32 curValue, uint32 maxValue, uint16 regenField, uint32* lastRegen)
{
    if (curValue < maxValue)
    {
	    uint32 regenDelay = 6000; //standing
		if ((getUpdateValue(UNIT_FIELD_BYTES_1) & 0xff) == 1) regenDelay = 3000; //sitting
		else if ((getUpdateValue(UNIT_FIELD_BYTES_1) & 0xff) == 3) regenDelay = 1000; //sleeping
//        if ((getUpdateValue(UNIT_FIELD_BYTES_1) & 0xff) == 1)  
		{// sitting
            regenDelay = 3000;
        }

        // check if it's time to regen health
        if(m_regenTimer == 0)
        {
            m_regenTimer = regenDelay - 2 * getUpdateValue(UNIT_FIELD_STAT3);

            // Cheap mod by mstic :)
            // Changes hp/Mana regen to a percent of Stamina / Spirit currently 15%
			//Follower: Say it with me people "code,test,Have other people test, then commit.
            switch (regenField)
            {
            case UNIT_FIELD_HEALTH :  
				curValue+=uint32((getUpdateValue(UNIT_FIELD_STAT2) * .15)); 
                printf("Regenerating Life...\n");
                break;
            case UNIT_FIELD_POWER1 : 
				curValue+=uint32((getUpdateValue(UNIT_FIELD_STAT4) * .15));
                printf("Regenerating Mana...\n");
                break;
            default : curValue = 2;
                printf("Regenerating Default...\n");
                break;
            }

            if (curValue > maxValue) curValue = maxValue;
            setUpdateValue(regenField, curValue);
        }
    }
	return curValue;
}
*/


void Character::SwapItemInSlot(int srcslot, int destslot)
{
    uint32 tempguid1, tempitemid;
    tempguid1 = this->m_items[srcslot].guid;
    tempitemid = this->m_items[srcslot].itemid;
    this->m_items[srcslot].guid = this->m_items[destslot].guid;
    this->m_items[srcslot].itemid = this->m_items[destslot].itemid;
    this->m_items[destslot].guid = tempguid1;
    this->m_items[destslot].itemid = tempitemid;
}

void Character::BuildEnumData( uint8 * data, uint8 * length )
{
    /*
    oint64      id; 
    char      Name[MAX_CHARACTER_NAME_SIZE]; 
    obyte      Race; 
    obyte      Class; 
    obyte      Gender; 
    obyte      Skin; 
    obyte      Face; 
    obyte      HairStyle; 
    obyte      HairColour; 
    obyte      FacialHair; 
    obyte      Level; 
    obyte      OutfitID; 
    oint32      ZoneID; 
    obyte      unknown1; 
    obyte      unknown2; 
    obyte      unknown3; 
    ofloat32   PositionX; 
    ofloat32   PositionY; 
    ofloat32   PositionZ; 
    oint32      GuildID; 
    oint32      unknown4; 
    obyte      rest; 
    oint32      PetDisplayInfoID; 
    oint32      PetExperienceLevel; 
    oint32      PetCreatureFamilyID; 
    InventoryItem_t      InventoryItem[20]; 
    */
    uint8 i = 0, doo = 0;
    assert(data);

    memcpy(data, &m_guid[0], 4);
    memcpy(data+4, &m_guid[1], 4);
    doo=8;

    // name
    uint16 name_size = 0;
    for (i=0; m_name[i] != 0; i++){
        name_size++;
        data[doo++] = m_name[i];
    }

    assert( name_size <= 21 );

    data[doo++] = 0x00;

    uint32 bytes = getUpdateValue(UNIT_FIELD_BYTES_0);
    data[doo++] = uint8(bytes & 0xff); // race
    data[doo++] = uint8((bytes >> 8) & 0xff); // class
    data[doo++] = uint8((bytes >> 16) & 0xff); // gender

    bytes = getUpdateValue(PLAYER_BYTES);
    data[doo++] = uint8(bytes & 0xff); //skin 
    data[doo++] = uint8((bytes >> 8) & 0xff); //face
    data[doo++] = uint8((bytes >> 16) & 0xff); //hairstyle
    data[doo++] = uint8((bytes >> 24) & 0xff); //haircolor

    bytes = getUpdateValue(PLAYER_BYTES_2);
    data[doo++] = uint8((bytes >> 8) & 0xff); //facialhair

    data[doo++] = uint8(getUpdateValue(UNIT_FIELD_LEVEL)); //level

    memcpy(data+doo, &m_zoneId, 2); // zoneid
    doo+=2;
    data[doo++] = 0x00;
    data[doo++] = 0x00;

    memcpy(data+doo, &m_mapId, 2); // mapid
    doo+=2;
    data[doo++] = 0x00;
    data[doo++] = 0x00;

    memcpy(data+doo, &m_positionX, 4); //x
    doo+=4;

    memcpy(data+doo, &m_positionY, 4); //y
    doo+=4;

    memcpy(data+doo, &m_positionZ, 4); //z
    doo+=4;

    /*    data[doo++] = ((uint8)((m_guildId>>8) & 0xFF)); //guild
    data[doo++] = (uint8)(m_guildId);
    data[doo++] = ((uint8)((m_petInfoId>>8) & 0xFF)); 
    data[doo++] = (uint8)(m_petInfoId);
    data[doo++] = ((uint8)((m_petLevel>>8) & 0xFF));
    data[doo++] = (uint8)(m_petLevel);
    data[doo++] = 0; // lower half of unknown uint16
    data[doo++] = 0; // upper half of unknown uints16
    data[doo++] = 1; // 1=well rested., 2=rested, 3=normal, 4=tired, 5=exhausted
    data[doo++] = ((uint8)((m_petFamilyId>>8) & 0xFF));
    data[doo++] = (uint8)(m_petFamilyId);
    */
    int tempstor = 0xffffffff;
    memcpy(data+doo, &tempstor, 4); //guild
    doo+=4;
    tempstor = 0;
    memcpy(data+doo, &tempstor, 4); //unknown
    doo+=4;
    data[doo++] = 1; //rest state
    memcpy(data+doo, &m_petInfoId, 4); //pet info id
    doo+=4;
    memcpy(data+doo, &m_petLevel, 4); //pet info id
    doo+=4;
    memcpy(data+doo, &m_petFamilyId, 4); //pet info id
    doo+=4;



    Item *tempitem;
    for (i = 0; i < 20; i++) {
        tempitem = WorldServer::getSingleton().GetItem(m_items[i].itemid);
        if ((tempitem == NULL) && (m_items[i].guid != 0))
            return;
        if (m_items[i].guid != 0) {
            memcpy(data+doo, &tempitem->DisplayInfoID, 4);
            doo+=4;
            data[doo++] = uint8(tempitem->Inventorytype);
        }
        else {
            memcpy(data+doo, &m_inventory[i].displayId, 4);
            doo+=4;
            data[doo++] = i;
        }
    }
    // pad out the rest
    while (doo-name_size < 159){
        data[doo++] = 0x00;
    }

    assert( doo <= 176 );

    *length = name_size + 159;

}


void Character::BuildUpdateBlock(UpdateMask* updateMask, uint8 * data, int* length)
{
    Unit::BuildUpdateBlock(updateMask, data, length);
}



/////////////////////////////////// QUESTS ////////////////////////////////////////////
uint32 Character::getQuestStatus(uint32 quest_id)
{
    if( mQuestStatus.find( quest_id ) == mQuestStatus.end( ) ) return 0;
    return mQuestStatus[quest_id].status;
}

uint32 Character::addNewQuest(uint32 quest_id, uint32 status)
{ 
    quest_status qs;
    qs.quest_id = quest_id;
    qs.status = status;

    mQuestStatus[quest_id] = qs;
    return status; 
};

void Character::loadExistingQuest(quest_status qs)
{
    mQuestStatus[qs.quest_id] = qs;
}

void Character::setQuestStatus(uint32 quest_id, uint32 new_status)
{ 
    assert( mQuestStatus.find( quest_id ) != mQuestStatus.end( ) );
    mQuestStatus[quest_id].status = new_status; 
}
 
/*
uint16 Character::getOpenQuestSlot()
{
    int start = PLAYER_QUEST_LOG_1_1;
    int end = PLAYER_QUEST_LOG_1_1 + 80;
    for (int i = start; i <= end; i+=4)
        if (m_updateValues[i] == 0)
            return i;

    return 0;
}

uint16 Character::getQuestSlot(uint32 quest_id)
{
    int start = PLAYER_QUEST_LOG_1_1;
    int end = PLAYER_QUEST_LOG_1_1 + 80;
    for (int i = start; i <= end; i+=4)
        if (m_updateValues[i] == quest_id)
            return i;

    return 0;
}
*/ 
 
uint16 Character::getOpenQuestSlot()  
{  
    int start = PLAYER_QUEST_LOG_1_1;  
   int end = PLAYER_QUEST_LOG_1_1 + 60;  
   for (int i = start; i <= end; i+=3)  
        if (m_updateValues[i] == 0)  
            return i;  
 
    return 0;  
}  
 
uint16 Character::getQuestSlot(uint32 quest_id)  
{  
    int start = PLAYER_QUEST_LOG_1_1;  
   int end = PLAYER_QUEST_LOG_1_1 + 60;  
   for (int i = start; i <= end; i+=3)  
        if (m_updateValues[i] == quest_id)  
            return i;  
 
    return 0;  
} 

void Character::setQuestLogBits(UpdateMask *updateMask)
{
    for( StatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++ i ) {
        if (i->second.status == 3){ // incomplete, put the quest in the log
            uint16 log_slot = getQuestSlot(i->second.quest_id);
            struct quest_status qs = i->second;
            if (log_slot == 0){ // in case this quest hasnt been added to the updateValues (but it shoudl have been!)
                log_slot = getOpenQuestSlot();
                setUpdateValue(log_slot, qs.quest_id);
                setUpdateValue(log_slot+1, 0x337);
            }

            updateMask->setBit(log_slot);
            updateMask->setBit(log_slot+1); 

            if (qs.m_questMobCount[0] > 0 || qs.m_questMobCount[1] > 0 ||
                qs.m_questMobCount[2] > 0 || qs.m_questMobCount[3] > 0)
            {
                updateMask->setBit(log_slot+2);
            }
        }
    }
}


void Character::KilledMonster(uint32 entry, uint32 guid)
{
    for( StatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++ i ) {
        if (i->second.status == 3){
            Quest *pQuest = WorldServer::getSingleton().getQuest(i->first);
            for (int j=0; j<4; j++)
            {
                if (pQuest->m_questMobId[j] == entry)
                {
                    if (i->second.m_questMobCount[j]+1 <= pQuest->m_questMobCount[j])
                    {
                        i->second.m_questMobCount[j]++ ;

                        // Send Update quest update kills message
                        wowWData data;
                        data.Initialise(24, SMSG_QUESTUPDATE_ADD_KILL);
                        data << pQuest->m_questId;
                        data << uint32(pQuest->m_questMobId[j]);
                        data << uint32(i->second.m_questMobCount[j]);
                        data << uint32(pQuest->m_questMobCount[j]);
                        data << guid << 0xF0001000;
                        WorldServer::getSingleton().SendMessageToPlayer(&data, m_name);

                        // update journal
                        // this is crazy.  each bit corresponds to a kill, set multiple bits to signify multiple kills
                    /*  uint32 start_bit=0;
                        if (j-1 < 0) start_bit = 0;
                        else
                            for (int n=j-1; n>=0; n--)
                                start_bit += pQuest->m_questMobCount[n];

                        uint16 log_slot = getQuestSlot(pQuest->m_questId);
                        uint32 kills = getUpdateValue(log_slot+2);

                        int exp = start_bit + i->second.m_questMobCount[j]-1;
                        kills |= 1 << exp;
                        setUpdateValue(log_slot+2, kills); */
                     
					 
						// it's not so crazy if you know what you're doing...  
						uint16 log_slot = getQuestSlot(pQuest->m_questId);  
						uint32 kills = getUpdateValue(log_slot+1);  
						kills = kills + (1 << (6*j));   // 6 bits per mob counter  
						setUpdateValue(log_slot+1, kills);					 
					 
					}

                    checkQuestStatus(i->second.quest_id);
                    // Ehh, I think a packet should be sent here, but I havent found one in the official logs yet

                    return;
                } // end if mobId == entry
            } // end for each mobId
        } // end if status == 3
    } // end for each quest
}

//======================================================
//  Check to see if all the required monsters and items
//  have been killed and collected.
//======================================================
bool Character::checkQuestStatus(uint32 quest_id)
{
    assert( mQuestStatus.find( quest_id ) != mQuestStatus.end( ) );
    quest_status qs = mQuestStatus[quest_id];
    Quest *pQuest = WorldServer::getSingleton().getQuest(quest_id);

    if (qs.m_questItemCount[0] == pQuest->m_questItemCount[0] &&
        qs.m_questItemCount[1] == pQuest->m_questItemCount[1] &&
        qs.m_questItemCount[2] == pQuest->m_questItemCount[2] &&
        qs.m_questItemCount[3] == pQuest->m_questItemCount[3] &&
        qs.m_questMobCount[0] == pQuest->m_questMobCount[0] &&
        qs.m_questMobCount[1] == pQuest->m_questMobCount[1] &&
        qs.m_questMobCount[2] == pQuest->m_questMobCount[2] &&
        qs.m_questMobCount[3] == pQuest->m_questMobCount[3])
    {
        // Quest complete!
        return true;
    }

    return false;
}


//  This function sends the message displaying the purple XP gain for the char
//  It assumes you will send out an UpdateObject packet at a later time.
void Character::giveXP(uint32 xp_to_give, uint32 guidlow, uint32 guidhi)
{
    wowWData data;
    if (guidlow != 0)
    {      
        // Send out purple XP gain message, but ONLY if a valid GUID was passed in
        // This message appear to be only for gaining XP from a death
        data.Initialise(17, SMSG_LOG_XPGAIN);
        data << uint32(guidlow) << uint32(guidhi);
        data << uint32(xp_to_give);
        data << uint8(0) << uint16(xp_to_give) << uint8(0);
        data << uint8(0);
        WorldServer::getSingleton().SendMessageToPlayer(&data, m_name);
    }

	if (xp_to_give == 0) return;

    uint32 xp           = getUpdateValue(PLAYER_XP);
    uint32 next_lvl_xp  = getUpdateValue(PLAYER_NEXT_LEVEL_XP);
    uint32 new_xp       = xp + xp_to_give;

    // Check for level-up
    if (new_xp >= next_lvl_xp)
    {
/* old lvlup
        uint32 health_gain=1, mana_gain=1;
        // Level-Up!
        new_xp = new_xp - next_lvl_xp;  // reset XP to 0, but add extra from this xp add
        next_lvl_xp += next_lvl_xp/2;   // set the new next level xp
        uint16 level = (uint16)getUpdateValue(UNIT_FIELD_LEVEL) + 1;    // increment the level
 
		setUpdateValue(PLAYER_NEXT_LEVEL_XP,    next_lvl_xp); 
        setUpdateValue(UNIT_FIELD_LEVEL,        level); 
 
		health_gain = m_health; 
		mana_gain = m_mana; 

		giveStat(); 
 
		health_gain = m_health - health_gain; 
		mana_gain = m_mana - mana_gain; 
*/
 
        uint32 health_gain=0, new_health=0, mana_gain=0, new_mana=0;
        new_xp = new_xp - next_lvl_xp;
        uint16 level = (uint16)getUpdateValue(UNIT_FIELD_LEVEL) + 1;
		next_lvl_xp = ((8*level*((level*5) + 45))/100)*100;
		//next_lvl_xp = level*level*400;

		health_gain = getUpdateValue(UNIT_FIELD_STAT2);
        new_health = getUpdateValue(UNIT_FIELD_MAXHEALTH) + health_gain;

        if (getUpdateValue(UNIT_FIELD_MAXPOWER1) > 0){
			mana_gain = getUpdateValue(UNIT_FIELD_STAT4);
            new_mana = getUpdateValue(UNIT_FIELD_MAXPOWER1) + mana_gain;
        }

		giveStat();
 
		updateItemStats(); 

        data.Initialise(48, SMSG_LEVELUP_INFO);

        data << uint32(level);
        data << uint32(health_gain);     // health gain
        data << uint32(mana_gain);       // mana gain
        data << uint32(0);
        data << uint32(0);
        data << uint32(0);

        // 6 new fields
        data << uint32(0);  
        data << uint32(stat0);  //strength
        data << uint32(stat1);  //agility
        data << uint32(stat2);  //stamina
        data << uint32(stat3);  //intelect
        data << uint32(stat4);  //spirit
 
		setUpdateValue(UNIT_FIELD_STAT0,		m_stat0+stat0); 
		setUpdateValue(UNIT_FIELD_STAT1,		m_stat1+stat1); 
		setUpdateValue(UNIT_FIELD_STAT2,		m_stat2+stat2); 
		setUpdateValue(UNIT_FIELD_STAT3,		m_stat3+stat3); 
		setUpdateValue(UNIT_FIELD_STAT4,		m_stat4+stat4); 
		setUpdateValue(UNIT_FIELD_MAXHEALTH,    new_health); 
		setUpdateValue(UNIT_FIELD_HEALTH,       new_health); 
		setUpdateValue(UNIT_FIELD_POWER1,       new_mana); 
		setUpdateValue(UNIT_FIELD_MAXPOWER1,    new_mana); 
		setUpdateValue(UNIT_FIELD_LEVEL,		level); 
		setUpdateValue(PLAYER_NEXT_LEVEL_XP,	next_lvl_xp); 

		if(level >= 10)
		{
			setUpdateValue(PLAYER_CHARACTER_POINTS1, getUpdateValue(PLAYER_CHARACTER_POINTS1) + 1);
		}
        WorldServer::getSingleton().SendMessageToPlayer(&data, m_name);
    }

    // Set the update bit
    setUpdateValue(PLAYER_XP, new_xp);
}
 
void Character::giveStat() 
{ 
	uint16 level = getUpdateValue(UNIT_FIELD_LEVEL); 
 
	switch( getClass() ) 
	{ 
	case SHAMAN: 
	case PRIEST: 
	case DRUID: 
	case WARLOCK: 
	case MAGE: 
		{ 
			stat0 +=1; 
			stat1 +=1; 
			stat2 +=1; 
			stat3 +=2; 
			stat4 +=2; 
 
			if(level > 30 ) 
			{ 
				stat3 +=1; 
				stat4 +=1; 
			} 
		}break; 
 
	case WARRIOR: 
	case PALADIN: 
	case HUNTER: 
	case ROGUE: 
		{ 
			stat0 +=2; 
			stat1 +=1; 
			stat2 +=2; 
			stat3 +=1; 
			stat4 +=1; 
 
			if(level > 30 ) 
			{ 
				stat0 +=1; 
				stat1 +=1; 
			} 
		}break; 
	} 
/* 
	m_health = getUpdateValue(UNIT_FIELD_MAXHEALTH) + m_stat2 / 2; 
 
	if (getUpdateValue(UNIT_FIELD_POWER1) > 0) 
	{ 
		m_mana = getUpdateValue(UNIT_FIELD_POWER1) + m_stat4 / 2; 
	}	 
	setUpdateValue(UNIT_FIELD_MAXHEALTH,    m_health); 
	setUpdateValue(UNIT_FIELD_HEALTH,       m_health); 
	setUpdateValue(UNIT_FIELD_POWER1,       m_mana); 
	setUpdateValue(UNIT_FIELD_MAXPOWER1,    m_mana); 
*/
}

////////////////////////////////////////////////////////////////////////////////
//  Fill the object's Update Values from a space deliminated list of values.
////////////////////////////////////////////////////////////////////////////////
void Character::LoadUpdateValues(uint8* data)
{
    char* next = strtok((char*)data, " ");
    m_updateValues[0] = atol(next);
    for( uint16 index = 1; index < UPDATE_BLOCKS; index++)
    {
        char* next = strtok(NULL, " ");
        if (!next) continue;
        m_updateValues[index] = atol(next);
        assert(m_updateValues[index] != 0x7FFFFFFF);
    }
	m_updateValues[UNIT_FIELD_NATIVEDISPLAYID] = m_updateValues[UNIT_FIELD_DISPLAYID];
}


///////////////////////////////////////////////////////////////////////////////
//	Items Update
///////////////////////////////////////////////////////////////////////////////
void Character::updateItemStats()
{
	uint32 Stat; 
	uint8 Amount; 
 
	uint8 tMStat0=0; 
	uint8 tMStat1=0; 
	uint8 tMStat2=0; 
	uint8 tMStat3=0; 
	uint8 tMStat4=0; 
	uint32 tRes1=0; 
	uint32 tRes2=0; 
	uint32 tRes3=0; 
	uint32 tRes4=0; 
	uint32 tRes5=0; 
	uint32 tRes6=0; 
	uint32 tArmor=0; 
	uint32 tHealth=0; 
	uint32 tMana=0;  
 
	for(int i=0; i < 20; i++)  
	{  
		if (this->m_items[i].guid > 1 )  
		{  
			Stat = world.GetItem(m_items[i].itemid)->Resistances[0]; 
		    tArmor += Stat;  
 
			Stat = world.GetItem(m_items[i].itemid)->Resistances[1];  
	  		tRes2 += Stat;  
 
			Stat = world.GetItem(m_items[i].itemid)->Resistances[2];  
			tRes3 += Stat;  
 
			Stat = world.GetItem(m_items[i].itemid)->Resistances[3];  
			tRes4 += Stat;  
 
			Stat = world.GetItem(m_items[i].itemid)->Resistances[4];  
			tRes5 += Stat;  
 
			Stat = world.GetItem(m_items[i].itemid)->Resistances[5];  
			tRes6 += Stat;  
 
			for(int j=0 ; j<5 ; j++) 
			{ 
				Stat = world.GetItem(m_items[i].itemid)->BonusStat[j]; 
				Amount = world.GetItem(m_items[i].itemid)->BonusAmount[j]; 
				//printf("J: %u STAT %u, AMOUNT: %u\n", j, Stat, Amount); 
				switch(Stat) 
				{ 
				case 0: //MANA 
					tMana += Amount;										 
					break; 
				case 1: //HEATLH 
					tHealth += Amount;									 
					break; 
				case 3: //AGILITY 
					tMStat1 += Amount; 
					break; 
				case 4: //STRENGTH 
					tMStat0 += Amount; 
					break; 
				case 5: //INTELLECT 
					tMStat3 += Amount; 
					break; 
				case 6: //SPIRIT 
					tMStat4 += Amount; 
					break; 
				case 7: //STAMINA 
					tMStat2 += Amount; 
					break; 
				//default: 
					//printf("WRONG STAT %u\n",Stat); 
				} 
			} 
		}  
	} 
 
	setUpdateValue(UNIT_FIELD_RESISTANCES, tArmor); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+1,tRes1); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+2,tRes2); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+3,tRes3); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+4,tRes4); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+5,tRes5); 
	setUpdateValue(UNIT_FIELD_RESISTANCES+6,tRes6); 
 
	setUpdateValue(PLAYER_FIELD_POSSTAT0, tMStat0); 
	setUpdateValue(PLAYER_FIELD_POSSTAT1, tMStat1); 
	setUpdateValue(PLAYER_FIELD_POSSTAT2, tMStat2); 
	setUpdateValue(PLAYER_FIELD_POSSTAT3, tMStat3); 
	setUpdateValue(PLAYER_FIELD_POSSTAT4, tMStat4); 
/* 
	if(getUpdateValue(UNIT_FIELD_HEALTH)> m_health+tHealth+(tMStat2/2)) 
	{ 
		setUpdateValue(UNIT_FIELD_HEALTH,m_health+tHealth+(tMStat2/2)); 
	} 
	setUpdateValue(UNIT_FIELD_MAXHEALTH,m_health+tHealth+(tMStat2/2)); 
 
	if (getUpdateValue(UNIT_FIELD_MAXPOWER1) > 0) 
	{ 
		if(getUpdateValue(UNIT_FIELD_POWER1)> m_mana+tMana+(tMStat4/2)) 
		{ 
			setUpdateValue(UNIT_FIELD_POWER1,m_mana+tMana+(tMStat4/2)); 
		} 
		setUpdateValue(UNIT_FIELD_MAXPOWER1,m_mana+tMana+(tMStat4/2)); 
	} 
*/ 
/* 
	UNIT_FIELD_POWER2 
	UNIT_FIELD_POWER3 
	UNIT_FIELD_POWER4 
	UNIT_FIELD_POWER5 
	UNIT_FIELD_MAXPOWER2 
	UNIT_FIELD_MAXPOWER3 
	UNIT_FIELD_MAXPOWER4 
	UNIT_FIELD_MAXPOWER5 
*/ 
 
	uint32 iMinDamage; 
	uint32 iMaxDamage; 
	uint32 baseattacktime; 
    if (this->getGuidBySlot(15) == 0) 
    { 
        iMinDamage = (m_stat0+tMStat0)/10 - 1; 
		iMaxDamage = (m_stat0+tMStat0)/10; 
		baseattacktime = 5000; 
    } 
    else  
	{ 
		iMinDamage = (m_stat0+tMStat0)/6 + world.GetItem(this->getItemIdBySlot(15) )->MinimumDamage[0]; 
		iMaxDamage = (m_stat0+tMStat0)/6 + world.GetItem(this->getItemIdBySlot(15) )->MaximumDamage[0]; 
		baseattacktime = (uint32)world.GetItem(this->getItemIdBySlot(15))->Delay; 
    } 
 
	setUpdateValue(UNIT_FIELD_BASEATTACKTIME, baseattacktime );
	setUpdateFloatValue(UNIT_FIELD_MINDAMAGE, float(iMinDamage) ); 
	setUpdateFloatValue(UNIT_FIELD_MAXDAMAGE, float(iMaxDamage) ); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, 0); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, 0); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 1, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 2, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 3, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 4, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 5, 1); 
	setUpdateFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + 6, 1); 
				 
	uint32 tmpAttackPower = ( iMinDamage + (iMaxDamage - iMinDamage) ) * 8 + 7; 
	setUpdateValue(UNIT_FIELD_ATTACKPOWER, tmpAttackPower); 
//	setUpdateValue(PLAYER_FIELD_ATTACKPOWERMODPOS, 0 ); 
//	setUpdateValue(PLAYER_FIELD_ATTACKPOWERMODNEG, 0 );
}


void Character::smsg_InitialSpells()
{
    wowWData data;
    uint16 spellCount = m_spells.size();

    data.Initialise(3+(4*spellCount), SMSG_INITIAL_SPELLS);
    data << uint8(0);
    data << uint16(spellCount); // spell count

    std::list::iterator itr;
    for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
    {
        data << uint16(itr->spellId); // spell id
        data << uint16(itr->slotId); // slot
    }

    world.SendMessageToPlayer(&data, m_name);
    printf( "CHARACTER: Sent Initial Spells\n" );
}

void Character::addSpell(uint16 spell_id, uint16 slot_id)
{
    struct spells newspell;
    newspell.spellId = spell_id;

    if (slot_id == 0xffff){
        uint16 maxid = 0;
        std::list::iterator itr;
        for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
        {
            if (itr->slotId > maxid) maxid = itr->slotId;
        }

        slot_id = maxid + 1;
    }

    newspell.slotId = slot_id;
    m_spells.push_back(newspell);
}
 
 
//START OF LINA LEARNED SPELL TEST 
bool Character::isAllreadyLearned(uint16 spell_id) 
{ 
	std::list::iterator itr; 
	for (itr = m_spells.begin(); itr != m_spells.end(); ++itr) 
	{ 
		if( itr->spellId == spell_id) return true; 
	} 
	return false; 
} 
//END OF LINA LEARNED SPELL TEST 
 
 
//START OF LINA ACTION BAR 
void Character::smsg_InitialActions() 
{ 
    wowWData data; 
    uint16 actionCount = m_actions.size(); 
	uint16 button=0; 
 
    data.Initialise(480, SMSG_ACTION_BUTTONS); 
 
    std::list::iterator itr; 
    for (itr = m_actions.begin(); itr != m_actions.end();) 
    { 
		//printf("BUTTON: %u == %u\n", itr->button, button); 
		if( itr->button == button) 
		{ 
			data << uint16(itr->action); 
			data << uint8(itr->type); 
			data << uint8(itr->misc); 
			//printf("SET: button %u action %u\n",button,itr->action); 
			++itr; 
		} 
		else 
		{ 
			data << uint32(0); 
		} 
		button++; 
    } 
	if(button < 120 ) 
	{ 
		for(int temp_counter=(120-button); temp_counter>0; temp_counter--) 
		{ 
			data << uint32(0); 
		} 
	} 
    world.SendMessageToPlayer(&data, m_name); 
    printf( "CHARACTER: Sent Initial Actions\n" ); 
} 
 
void Character::addAction(uint8 button, uint16 action, uint8 type, uint8 misc) 
{ 
	bool isexist=false; 
 
	std::list::iterator itr; 
	for (itr = m_actions.begin(); itr != m_actions.end(); ++itr) 
	{ 
		if (itr->button == button) 
		{ 
			if(action==0) 
			{ 
				//printf("ERASE: button %u action %u\n",itr->button,itr->action); 
				m_actions.erase(itr); 
			} 
			else 
			{ 
				//printf("OLD: button %u action %u\n",itr->button,itr->action); 
				itr->button=button; 
				itr->action=action; 
				itr->type=type; 
				itr->misc=misc; 
				//printf("UPDATE: button %u action %u\n",itr->button,itr->action); 
			} 
			isexist=true; 
			break; 
		} 
	} 
	if( !isexist ) 
	{ 
		//printf("ADD: button %u action %u\n",button,action); 
		struct actions newaction; 
		newaction.button=button; 
		newaction.action=action; 
		newaction.type=type; 
		newaction.misc=misc; 
		m_actions.push_back(newaction); 
	} 
} 
//END OF LINA ACTION BAR