Exemplo n.º 1
0
void CTurtle::Update(float fElapsedTime)
{
	m_vAnimations[m_nCurrAnimation].Update(fElapsedTime);
	if(GetExperience() >= (100 * GetLevel()))
	{
		CBattleMap::GetInstance()->PlaySFX(CAssets::GetInstance()->aBMcowabungaSnd);
		SetExperience(0/*GetExperience()-(100* GetLevel())*/);
		SetLevel(GetLevel() + 1);
		SetHealthMax((int)((float)GetMaxHealth() * 1.25f));
		SetHealth((int)((float)GetMaxHealth()));
		SetBaseAP(GetBaseAP()+2);
		SetStrength( (int)( (float)GetStrength() * 1.2f ) );
		SetDefense( (int) ( (float)GetDefense() * 1.2f ) );
		SetAccuracy( (int) ( (float)GetAccuracy() * 1.2f ) );
		SetSpeed( (int) ( (float)GetSpeed() * 1.2f ) );
	}
	if( GetHealth() <= 0)
	{
		if(GetAlive() == true)
		{
			CBattleMap::GetInstance()->DecrementNumChars();
			CBattleMap::GetInstance()->DecrementNumTurtles();
			CBattleMap::GetInstance()->SetTurtleDead();
			SetAlive(false);
			if(GetCurrAnimNum() != 9)
				SetCurrAnim(9);
			SetPosZ(0.9f);
		}
	}
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
Vector CBaseTFPlayer::GenerateFireVector( Vector *viewVector )
{
	// Calculate the weapon spread from the player's accuracy
	float flAcc = (GetAccuracy() * 0.5) / ACCURACY_DISTANCE;
	float flAccuracyAngle = RAD2DEG( atan( flAcc ) );
	// If the user passed in a viewVector, use it, otherwise use player's v_angle
	Vector angShootAngles = viewVector ? *viewVector : pl->v_angle;
	if ( flAccuracyAngle )
	{
		float x, y, z;
		do {
			x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
			y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
			z = x*x+y*y;
		} while (z > 1);

		angShootAngles.x = UTIL_AngleMod( angShootAngles.x + (x * flAccuracyAngle) );
		angShootAngles.y = UTIL_AngleMod( angShootAngles.y + (y * flAccuracyAngle) );
	}
	
	Vector forward;
	AngleVectors( angShootAngles, &forward );
	return forward;
}
void    CprobeIGC::Update(Time now)
{
    if (now >= m_timeExpire)	
        GetMyMission()->GetIgcSite()->KillProbeEvent(this);
    else
    {
        {
            float   dt = m_probeType->GetRipcordDelay();
            if (dt >= 0.0f)
            {
                Time    timeActivate = m_time0 + dt;
                if ((GetMyLastUpdate() < timeActivate) &&
                    (now >= timeActivate))
                {
                    GetMyMission()->GetIgcSite()->ActivateTeleportProbe(this);
                }
            }
        }

        if (m_projectileType)
        {
            if (m_nextFire < now)
            {
                IclusterIGC*    pcluster = GetCluster();
                assert (pcluster);

                //We'll be able to take a shot
                float   lifespan = GetProjectileLifespan();
                IsideIGC*   pside = GetSide();

                const Vector&       myPosition = GetPosition();

                float   speed = m_projectileType->GetSpeed();
                if (m_ammo != 0)
                    speed *= GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSpeedAmmo);

                float   accuracy = GetAccuracy();
                float   dtimeBurst = GetDtBurst();
                float   dispersion = m_probeType->GetDispersion();
                Time    lastUpdate = GetMyLastUpdate();
                if (m_nextFire < lastUpdate)
                    m_nextFire = lastUpdate;
                assert (m_nextFire <= now);

                TmodelIGC<IprobeIGC>::Update(now);

                float   dtUpdate = m_nextFire - lastUpdate;

                //If we have a target ... find the closest enemy ship who is a valid target
                ExpendableAbilityBitMask    eabm = m_probeType->GetCapabilities();
                float       distance2Min = speed * lifespan / 1.2f;
                distance2Min *= distance2Min;
                Vector      directionMin;



                ImodelIGC*  pmodelTarget = NULL;
                if (eabm & c_eabmShootOnlyTarget)
                {
                    if (m_target && (m_target->GetCluster() == pcluster))
                    {
                        ObjectType  type = m_target->GetObjectType();
                        ValidTarget((type == OT_ship) ? ((IshipIGC*)(ImodelIGC*)m_target)->GetSourceShip() : m_target,
                                    pside, myPosition, dtUpdate, accuracy, speed, lifespan, type,
                                    &pmodelTarget, &distance2Min, &directionMin);
                    }
                }
                else
                {
                    if (eabm & c_eabmShootShips)
                    {
                        //Threats to stations get highest priority
                        GetTarget((const ModelListIGC*)(pcluster->GetShips()),
                                  pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_ship,
                                  &pmodelTarget, &distance2Min, &directionMin);
                    }

                    if (eabm & c_eabmShootMissiles)
                    {
                        GetTarget((const ModelListIGC*)(pcluster->GetMissiles()),
                                  pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_missile, 
                                  &pmodelTarget, &distance2Min, &directionMin);
                    }

                    if (eabm & c_eabmShootStations)
                    {
                        GetTarget((const ModelListIGC*)(pcluster->GetStations()),
                                  pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_station, 
                                  &pmodelTarget, &distance2Min, &directionMin);
                    }
                }

                if (pmodelTarget)
                {
                    if (m_launcher && (m_launcher->GetMission() != GetMyMission()))
                        m_launcher = NULL;

                    //It is going to shoot ... make it visible to everyone in the sector
                    if (!m_bSeenByAll)
                    {
                        m_bSeenByAll = true;
                        for (SideLinkIGC*   psl = m_pMission->GetSides()->first();
                             (psl != NULL);
                             psl = psl->next())
                        {
                            IsideIGC*   psideOther = psl->data();

                            if (!SeenBySide(psideOther))
                            {
                                //Does this side have any scanners in the sector?
                                ClusterSite*    pcs = pcluster->GetClusterSite();
                                const ScannerListIGC*   psl = pcs->GetScanners(psideOther->GetObjectID());
                                if ((psl->n() != 0) || (m_pMission->GetMissionParams()->bAllowAlliedViz && psideOther->AlliedSides(psideOther,pside))) //ALLY 7/3/09 VISIBILITY 7/11/09 imago
                                    SetSideVisibility(psideOther, true);
                                else
                                    m_bSeenByAll = false;
                            }
                        }
                    }

                    //We have a target ... fire along directionMin (modulo dispersion)
                    Orientation o = GetOrientation();
                    o.TurnTo(directionMin);
                    SetOrientation(o);
                    Vector  position = myPosition + m_probeType->GetEmissionPt() * o;

                    DataProjectileIGC   dataProjectile;
                    dataProjectile.projectileTypeID = m_projectileType->GetObjectID();

                    short   nShots = 0;
                    do
                    {
                        //Permute the "forward" direction slightly by a random amount
                        dataProjectile.forward = directionMin;
                        if (dispersion != 0.0f)
                        {
                            float   r = random(0.0f, dispersion);
                            float   a = random(0.0f, 2.0f * pi);
                            dataProjectile.forward += (r * cos(a)) * o.GetRight();
                            dataProjectile.forward += (r * sin(a)) * o.GetUp();

                            dataProjectile.forward.SetNormalize();
                        }

                        //We never move, so skip all the velocity calculations
                        dataProjectile.velocity = speed * dataProjectile.forward;

                        dataProjectile.lifespan = lifespan;

                        IprojectileIGC*  p = (IprojectileIGC*)(m_pMission->CreateObject(m_nextFire, OT_projectile, 
                                                                                        &dataProjectile, sizeof(dataProjectile)));
                        assert (p);
                        {
                            p->SetLauncher(m_launcher ? ((ImodelIGC*)m_launcher) : ((ImodelIGC*)this));
                            p->SetPosition(position);

                            p->SetCluster(pcluster);

                            p->Release();
                        }

                        nShots++;
                        m_nextFire += dtimeBurst;
                    }
                    while (m_nextFire < now);

                    if (m_ammo > 0)
                    {
                        m_ammo -= nShots;
                        if (m_ammo <= 0)
                        {
                            m_ammo = 0;
                            GetMyMission()->GetIgcSite()->KillProbeEvent(this);
                        }
                    }
                }
                else
                {
                    //No shots this cycle
                    m_nextFire = now;
                }
            }
        }

        TmodelIGC<IprobeIGC>::Update(now);
    }
}
Exemplo n.º 4
0
void CCharacter::RefreshBuff( )
{
    bool bflag = false;
    for( UINT i=0;i<32;i++)
    {
        if(MagicStatus[i].Buff == 0) continue;
        clock_t etime = clock() - MagicStatus[i].BuffTime;
        if( etime >= MagicStatus[i].Duration * CLOCKS_PER_SEC )
        {

            Log(MSG_INFO,"Magic Status %i, vanish after: %i", MagicStatus[i].Status, MagicStatus[i].Duration);

            switch(MagicStatus[i].Status)
            {
                case STATUS_HP_8: case STATUS_HP_18: case STATUS_HP_30: case STATUS_HP_43: case STATUS_HP_58: case STATUS_HP_75: case STATUS_SUMMON_HP:
                case STATUS_HP_92: case STATUS_HP_111: case STATUS_HP_131: case STATUS_HP_152: case STATUS_HP_174: case STATUS_HP_197: case STATUS_HP_221:
                case STATUS_HP_246: case STATUS_HP_272: case STATUS_HP_299: case STATUS_HP_326: case STATUS_HP_354: case STATUS_HP_383: case STATUS_HP_413:
                case STATUS_HP_443: case STATUS_HP_475: case STATUS_HP_539: case STATUS_HP_572: case STATUS_HP_5_PC: case 115:
                {
                    Status->HPHeal = 0xff;
                }
                break;

                case STATUS_MP_6: case STATUS_MP_10: case STATUS_MP_14: case STATUS_MP_18: case STATUS_MP_21: case STATUS_MP_25: case STATUS_MP_29:
                case STATUS_MP_33: case STATUS_MP_36: case STATUS_MP_40: case STATUS_MP_44: case STATUS_MP_48: case STATUS_MP_51: case STATUS_MP_55:
                case STATUS_MP_59: case STATUS_MP_63: case STATUS_MP_66: case STATUS_MP_70: case STATUS_MP_74: case STATUS_MP_78: case STATUS_MP_81:
                case STATUS_MP_85: case STATUS_MP_89: case STATUS_MP_93: case STATUS_MP_96: case 116:
                {
                    Status->MPHeal = 0xff;
                }
                break;

                case 18: // attack power up
                case 19: // attack power down
                case 48: // attack power up
                {
                    if(i == BUFF_ATTACK_UP_POS)
                    {
                        Status->Attack_up = 0xff;
                    }
                    else
                    {
                        Status->Attack_down = 0xff;
                    }
                    Stats->Attack_Power = GetAttackPower( );
                }
                break;
                case 20: // def up
                case 21: // def down
                case 49: // def up
                {
                    if(i==BUFF_DEFENSE_UP_POS)
                    {
                        Status->Defense_up= 0xff;
                    }
                    else
                    {
                        Status->Defense_down = 0xff;
                    }
                    Stats->Defense = GetDefense( );
                }
                break;
                case 24: //Accuracy up
                case 25: //Accuracy down
                case 51: //attack Accuracy up.
                {
                    if(i==BUFF_HITRATE_UP_POS)
                    {
                        Status->Accuracy_up= 0xff;
                    }
                    else
                    {
                        Status->Accuracy_down = 0xff;
                    }
                    Stats->Accuracy = GetAccuracy( );
                }
                break;
                case 22: // macic resistance up
                case 23: // magic resistance down
                case 50: // magic resistance up
                {
                    if(i==BUFF_MDEFENSE_UP_POS)
                    {
                        Status->Magic_Defense_up = 0xff;
                    }
                    else
                    {
                        Status->Magic_Defense_down = 0xff;
                    }
                    Stats->Magic_Defense = GetMagicDefense( );
                }
                break;
                case 28: //dodge up
                case 29: //dodge down
                case 53: //dodge rate up
                {
                    if(i==BUFF_DODGE_UP_POS)
                    {
                        Status->Dodge_up = 0xff;
                    }
                    else
                    {
                        Status->Dodge_down = 0xff;
                    }
                    Stats->Dodge = GetDodge( );
                }
                break;
                case 14: //dash
                case 15: //slow
                case 46: //movement speed increased
                {
                    if(i==BUFF_DASH_UP_POS)
                    {
                        Status->Dash_up = 0xff;
                    }
                    else
                    {
                        Status->Dash_down = 0xff;
                    }
                    Stats->Move_Speed = GetMoveSpeed( );
                }
                break;
                case 16: // haste attack
                case 17: // slow attack
                case 47: // attack speed up
                {
                    if(i==BUFF_HASTE_UP_POS)
                    {
                        Status->Haste_up = 0xff;
                    }
                    else
                    {
                        Status->Haste_down = 0xff;
                    }
                    //Stats->Attack_Speed_Percent = GetAttackSpeedPercent( );
                }
                break;
                case 26: // crit up
                case 27: // crit down
                case 52: // crit up
                {
                    if(i==BUFF_CRITICAL_UP_POS)
                    {
                        Status->Critical_up = 0xff;
                    }
                    else
                    {
                        Status->Critical_down = 0xff;
                    }
                    Stats->Critical = GetCritical( );
                }
                break;
                case 12: // max HP up
                case 44: // max HP up
                {
                    if(i==BUFF_MAX_HP_POS)
                    {
                        Status->HP_up = 0xff;
                    }
                    else
                    {
                        Status->HP_down = 0xff;
                    }
                    Stats->MaxHP = GetMaxHP( );

                    if(Stats->HP > Stats->MaxHP)
                    {
                        Stats->HP = Stats->MaxHP;
                    }
                }
                break;
                case 13: // max MP up
                case 45: // max MP up
                {
                    if(i==BUFF_MAX_MP_POS)
                    {
                        Status->MP_up = 0xff;
                    }
                    else
                    {
                        Status->MP_down = 0xff;
                    }
                    Stats->MaxMP = GetMaxMP( );

                    if(Stats->MP > Stats->MaxMP)
                    {
                        Stats->MP = Stats->MaxMP;
                    }
                }
                break;
                case 32: // faint
                {
                    Status->Faint = 0xff;
                    Status->CanMove = true;
                    Status->CanCastSkill = true;
                    Status->CanAttack = true;
                    //printf("removing stun\n");
                }
                break;
                case 7: case 8: case 9: case 10: case 11: case 89: //poisoned
                {
                    Status->Poisoned = 0xff;
                    //printf("removing poison\n");
                }
                break;
                case 30: // muted
                {
                    Status->Muted = 0xff;
                    Status->CanCastSkill = true;
                }
                break;
                case 31: // sleep May need to be fixed later to accomodate multiple status effects.
                {
                    Status->Sleep = 0xff;
                    Status->CanMove = true;
                    Status->CanCastSkill = true;
                    Status->CanAttack = true;
                }
                break;
                case 36: //A_Extra_Damage:
                case 54: //A_GMExtra_Damage:
                case 83: //Valkyrie Charm:
                {
                    if(i==BUFF_DUMMY_DAMAGE_POS)
                    {
                        Status->ExtraDamage_up = 0xff;
                        Stats->ExtraDamage_add = 0;//We put extardamage add value to 0 if we lost the adddmg buff
                    }
                    else
                    {
                        Status->ExtraDamage_down = 0xff;
                        Stats->ExtraDamage_add = 0;//We put extardamage add value to 0 if we lost the adddmg buff
                    }
                }
                break;
                case 56: //Taunt
                {
                    Status->Taunt = 0xff;
                    //printf("removing Taunt\n");
                }
                break;
                case 58: case 61: case 74: case 77:  case 78: case 79: case 80: //flame
                {
                    Status->Flamed = 0xff;
                }
                break;
                case 33://Stealth,Camoflauge
                {
                    if(IsAttacking( ))
                    {
                        MagicStatus[i].Duration = 0;
                    }
                    Status->Stealth = 0xff;
                    //printf("removing Stealth\n");
                }
                break;
                case 86://Stealth,Weary
                {
                    Status->Weary = 0xff;
                    Status->CanCastSkill = true;
                    //printf("removing Weary\n");
                }
                break;
                case 34://Cloaking
                {
                    Status->Cloaking = 0xff;
                    //printf("removing Cloaking\n");
                }
                break;
                case 35: //ShieldDamage:
                {
                    if(i==BUFF_SHIELD_DAMAGE_POS)
                    {
                        Status->ShieldDamage_up = 0xff;
                        //Stats->ShieldDamage = 0xff;
                    }
                    else
                    {
                        Status->ShieldDamage_down = 0xff;
                        //Stats->ShieldDamage = 0xff;
                    }
                }
                break;
                case 55://Detect
                {
                    Status->Detect = 0xff;
                    Status->Cloaking = 0xff;
                    Status->Stealth = 0xff;
                    //printf("Detect Done\n");
                }
                break;
                case 38://Purify
                {
                    //Buff_Down
                    Status->Attack_down = 0xff;
                    Status->Defense_down = 0xff;
                    Status->Accuracy_down = 0xff;
                    Status->Magic_Defense_down = 0xff;
                    Status->Dodge_down = 0xff;
                    Status->Dash_down = 0xff;
                    Status->Haste_down = 0xff;
                    Status->Critical_down = 0xff;
                    Status->HP_down = 0xff;
                    Status->MP_down = 0xff;
                    Status->ExtraDamage_down = 0xff;
                    Status->ShieldDamage_down = 0xff;
                    Status->ALL_down = 0xff;

                    //Bad Status
                    //Status->Stun = 0xff;
                    Status->Poisoned = 0xff;
                    Status->Muted = 0xff;
                    Status->Sleep = 0xff;
                    Status->Flamed = 0xff;
                    Status->Faint = 0xff;

                    //Stats
                    Stats->Attack_Power = GetAttackPower( );
                    Stats->Defense = GetDefense( );
                    Stats->Accuracy = GetAccuracy( );
                    Stats->Magic_Defense = GetMagicDefense( );
                    Stats->Dodge = GetDodge( );
                    Stats->Move_Speed = GetMoveSpeed( );
                    Stats->Attack_Speed = GetAttackSpeed( );
                    //Stats->Attack_Speed_Percent = GetAttackSpeedPercent();
                    Stats->Critical = GetCritical( );
                    Stats->MaxHP = GetMaxHP( );
                    Stats->MaxMP = GetMaxMP( );
                    //printf("Purify Done\n");
                }
                break;
				case 39:// Dispell
                {
                    //Buff_Down
                    Status->Attack_down = 0xff;
                    Status->Defense_down = 0xff;
                    Status->Accuracy_down = 0xff;
                    Status->Magic_Defense_down = 0xff;
                    Status->Dodge_down = 0xff;
                    Status->Dash_down = 0xff;
                    Status->Haste_down = 0xff;
                    Status->Critical_down = 0xff;
                    Status->HP_down = 0xff;
                    Status->MP_down = 0xff;
                    Status->ExtraDamage_down = 0xff;
                    Status->ShieldDamage_down = 0xff;
                    Status->ALL_down = 0xff;

                    //Buff_Up
                    Status->Attack_up = 0xff;
                    Status->Defense_up = 0xff;
                    Status->Accuracy_up = 0xff;
                    Status->Magic_Defense_up = 0xff;
                    Status->Dodge_up = 0xff;
                    Status->Dash_up = 0xff;
                    Status->Haste_up = 0xff;
                    Status->Critical_up = 0xff;
                    Status->HP_up = 0xff;
                    Status->MP_up = 0xff;
                    Status->ExtraDamage_up = 0xff;
                    Status->ShieldDamage_up = 0xff;
                    Status->ALL_up = 0xff;

                    //Bad Status
                    //Status->Stun = 0xff;
                    Status->Poisoned = 0xff;
                    Status->Muted = 0xff;
                    Status->Sleep = 0xff;
                    Status->Flamed = 0xff;
                    Status->Faint = 0xff;

                    //Stats
                    Stats->Attack_Power = GetAttackPower( );
                    Stats->Defense = GetDefense( );
                    Stats->Accuracy = GetAccuracy( );
                    Stats->Magic_Defense = GetMagicDefense( );
                    Stats->Dodge = GetDodge( );
                    Stats->Move_Speed = GetMoveSpeed( );
                    Stats->Attack_Speed = GetAttackSpeed( );
                    Stats->Critical = GetCritical( );
                    Stats->MaxHP = GetMaxHP( );
                    Stats->MaxMP = GetMaxMP( );
                    //printf("Dispell Done\n");
                }
                break;
                default:
                {
                    Log(MSG_WARNING,"Unknow skill status in charfunctions %u.",MagicStatus[i].Status);
                }
            }
            BEGINPACKET( pak,0x7b7 );
            ADDWORD    ( pak, clientid );
            ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
            GServer->SendToVisible( &pak, this );
            MagicStatus[i].Status = 0;
            MagicStatus[i].Buff = 0;
            MagicStatus[i].BuffTime = 0;
            MagicStatus[i].Duration = 0;
            MagicStatus[i].Value = 0;
            bflag = true;
        }
        else if ( ((MagicStatus[i].Status >= 7 && MagicStatus[i].Status <= 11) || MagicStatus[i].Status == 89) && etime > 1*CLOCKS_PER_SEC) //Do poison dmg every 1.5 seconds
        {
             Stats->HP -= MagicStatus[i].Status; //Actually take 7, 8, 9, 10 or 11 from the health. Based on the Status itself, LMA: can be 89 noc too.
             MagicStatus[i].BuffTime += 1*CLOCKS_PER_SEC;
             MagicStatus[i].Duration -= 1;
             //printf("did %i poison dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);
             //Log(MSG_WARNING,"did %i poison dmg to the player / monster, still %i seconds and %I64i HP remain", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);

            //LMA: If dead, let's the client resynch
            if(IsDead())
            {
                BEGINPACKET( pak, 0x79f );
                ADDWORD    ( pak, clientid );
                ADDDWORD   ( pak, 1);
                GServer->SendToVisible( &pak, this );
                Log(MSG_INFO,"death poison for %i, amount: %i",clientid,MagicStatus[i].Status);
            }

             //A bunch of messy code to send dmg packet
             BEGINPACKET( pak, 0x7b6 );
             ADDWORD    ( pak, clientid );
             ADDWORD    ( pak, 0 );
             ADDDWORD   ( pak, 0x000007f8 );
             ADDBYTE    ( pak, 0x00 );
             ADDDWORD   ( pak, MagicStatus[i].Status );

             //If Enemy is killed
             if( IsDead())
             {
                 //printf("char died\n");
                 CDrop* thisdrop = NULL;
                 ADDDWORD   ( pak, 16 );
                 if( !IsSummon( ) && !IsPlayer( ))
                 {
                    //LMA: No drop if already dead and drop done.
                    if(drop_dead)
                    {
                        Log(MSG_WARNING,"Trying to make a monster (CID %u, type %u) drop again but already did.",clientid,char_montype);
                    }
                    else
                    {
                         thisdrop = GetDrop( );
                         if( thisdrop!=NULL)
                         {
                             CMap* map = GServer->MapList.Index[thisdrop->posMap];
                             map->AddDrop( thisdrop );
                         }

                    }

                 }

                 //GServer->SendToVisible( &pak, this, thisdrop );
                 GServer->SendToVisible( &pak, this);
             }
             else
             {
                 //If enemy is still alive
                 ADDDWORD   ( pak, 4 );
                 GServer->SendToVisible( &pak, this );
             }
         }
        else if ( MagicStatus[i].Status == 58 || MagicStatus[i].Status == 61 || MagicStatus[i].Status == 71 || MagicStatus[i].Status >= 77 && MagicStatus[i].Status <= 80 || MagicStatus[i].Status == 88 && etime > 1*CLOCKS_PER_SEC) //Do flame dmg every 1.5 seconds
        {
             Stats->HP -= MagicStatus[i].Status;
             MagicStatus[i].BuffTime += 1*CLOCKS_PER_SEC;
             MagicStatus[i].Duration -= 1;
             printf("did %i flame dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);

            //LMA: If dead, let's the client resynch
            if(IsDead())
            {
                BEGINPACKET( pak, 0x79f );
                ADDWORD    ( pak, clientid );
                ADDDWORD   ( pak, 1);
                GServer->SendToVisible( &pak, this );
                Log(MSG_INFO,"death flame for %i, amount: %i",clientid,MagicStatus[i].Status);
            }

             //A bunch of messy code to send dmg packet
             BEGINPACKET( pak, 0x7b6 );
             ADDWORD    ( pak, clientid );
             ADDWORD    ( pak, 0 );
             ADDDWORD   ( pak, 0x000007f8 );
             ADDBYTE    ( pak, 0x00 );
             ADDDWORD   ( pak, MagicStatus[i].Status );

             //If Enemy is killed
             if( IsDead())
             {
                 //printf("char died\n");
                 CDrop* thisdrop = NULL;
                 ADDDWORD   ( pak, 16 );
                 if( !IsSummon( ) && !IsPlayer( ))
                 {
                    //LMA: No drop if already dead and drop done.
                    if(drop_dead)
                    {
                        Log(MSG_WARNING,"Trying to make a monster (CID %u, type %u) drop again but already did.",clientid,char_montype);
                    }
                    else
                    {
                         thisdrop = GetDrop( );
                         if( thisdrop!=NULL)
                         {
                             CMap* map = GServer->MapList.Index[thisdrop->posMap];
                             map->AddDrop( thisdrop );
                         }

                    }

                 }
                 //GServer->SendToVisible( &pak, this, thisdrop );
                 GServer->SendToVisible( &pak, this);
             }
             else
             {
                 //If enemy is still alive
                 ADDDWORD   ( pak, 4 );
                 GServer->SendToVisible( &pak, this );
             }
         }

    }
    for( UINT i=0;i<32;i++)
    {
        if(MagicStatus2[i].Buff == 0) continue;
        clock_t etime = clock() - MagicStatus2[i].BuffTime;
        if( etime >= MagicStatus2[i].Duration * CLOCKS_PER_SEC )
        {
        CPlayer* thisplayer = GServer->GetClientByID(clientid);
            Log(MSG_INFO,"Magic Status %i, vanish after: %i", MagicStatus2[i].Status, MagicStatus2[i].Duration);

            switch(MagicStatus2[i].Status)
            {
                case 126: // ALLbuff up
                {
                    if(i == BUFF_ATTACK_UP_POS)
                    {
                        Status->Attack_up = 0xff;
                        thisplayer->Attr->ALLbuff = 0;
                    }
                    else
                    {
                        Status->Attack_down = 0xff;
                        thisplayer->Attr->ALLbuff = 0;
                    }
                }
                default:
                {
                    Log(MSG_WARNING,"Unknow skill status in charfunctions %u.",MagicStatus[i].Status);
                }
            }
            BEGINPACKET( pak,0x7b7 );
            ADDWORD    ( pak, clientid );
            ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
            GServer->SendToVisible( &pak, this );
            MagicStatus2[i].Status = 0;
            MagicStatus2[i].Buff = 0;
            MagicStatus2[i].BuffTime = 0;
            MagicStatus2[i].Duration = 0;
            MagicStatus2[i].Value = 0;
        }
    }
//    if(bflag)
//    {
//        BEGINPACKET( pak,0x7b7 );
//        ADDWORD    ( pak, clientid );
//        ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
//        GServer->SendToVisible( &pak, this );
//    }
}
// Attacks a target object.
void CHSLaser::AttackObject(CHSObject *cSource,
							CHSObject *cTarget,
							CHSConsole *cConsole,
							int iSysType)
{
	dbref dbUser;
	int   iAttackRoll;
	int   iDefendRoll;
	int i;
	CHSObject *cCTarget;
	double sX, sY, sZ; // Source object coords
	double tX, tY, tZ; // Target object coords;

	// Grab the user of the console.
	dbUser = hsInterface.ConsoleUser(cConsole->m_objnum);

	// Can we attack that object?
	if (cSource->GetType() == HST_SHIP)
	{
		CHSSysCloak *cCloak;
		CHSShip *ptr;
		float rval;

		ptr = (CHSShip *)cSource;

		// Look for the cloaking device.
		cCloak = (CHSSysCloak *)ptr->GetEngSystem(HSS_CLOAK);
		if (cCloak)
			if (cCloak->GetEngaged())
			{
				if (dbUser != NOTHING)
					hsStdError(dbUser, "You cannot fire while cloaked.");
				return;
			}
	}

	if (!CanAttackObject(cTarget))
	{
		if (dbUser != NOTHING)
			hsStdError(dbUser,
			"You cannot attack that target with that weapon.");
	}

 	// Calculate distance to object
	sX = cSource->GetX();
	sY = cSource->GetY();
	sZ = cSource->GetZ();
	tX = cTarget->GetX();
	tY = cTarget->GetY();
	tZ = cTarget->GetZ();

	double dDistance;
	dDistance = Dist3D(sX, sY, sZ, tX, tY, tZ) + .00001;

	// Size of a target ship matters relative to distance.
	// The closer a target gets to the ship, the larger
	// it effectively is.  That is to say it takes up more
	// of the view angle.  When the target is right next
	// to the ship, in front of the gun, it is essentially
	// the broad side of a barn, which everyone can hit.
	// Thus, to handle this we'll calculate the size of
	// the target and the viewing angle it takes up.

	double dSize; // Size of the side of the target
	double dAngle; // Amount of viewing angle taken up by size

	dSize = cTarget->GetSize();
	dSize = (.7 * dSize) * (.7 * dSize);

	// Halve the size, and divide by distance.  This
	// gives us the tangent of the angle taken up by
	// the target.
	dSize = (dSize * .5) / dDistance;

	// Take the inverse tangent to get angle.
	dAngle = atan(dSize);

	// Double the angle because we used half of the size
	// to get the angle of a right triangle.
	dAngle *= 2;

	// We now have the viewing angle consumed by the 
	// target.  There's a maximum possible value of 180,
	// so divide by that to determine how much of the viewing
	// angle is taken up by the target.
	dSize = dAngle * .005555;

	// Subtract from 1 to get maximum values of 1 when the
	// angle is small.
	dSize = 1 - dSize;

	// Now multiply by 6 to get relative difficulty of hitting
	// target.
	iDefendRoll = (int) (6 * dSize) + getrandom(6);
    iAttackRoll = GetAccuracy() + getrandom(6);

	// Simulate difficulty when a target is moving.
	// If the target is moving toward or away from the
	// attacker, it's not very difficult.  Thus, we
	// calculate the change in angle for the target
	// during one cycle.  The maximum change is 180
	// degrees.
	CHSVector tVec;
	CHSVector aVec;
	tVec = cTarget->GetMotionVector();
	aVec = cSource->GetMotionVector();

	// Calculate vector to target now.
	double dx, dy, dz;
	dx = tX - sX;
	dy = tY - sY;
	dz = tZ - sZ;

	// Make a unit vector
	dx /= dDistance;
	dy /= dDistance;
	dz /= dDistance;

	CHSVector nowVec(dx, dy, dz);

	// Now calculate coordinate for source and target
	// in one cycle.
	double sX2, sY2, sZ2;
	double tX2, tY2, tZ2;
	double aSpeed, tSpeed;

	// Grab both object speeds, and bring them down
	// to per-second levels.
	aSpeed = cSource->GetSpeed() * .0002778;
	tSpeed = cTarget->GetSpeed() * .0002778;

	// Calculate coordinates for next cycle.
	sX2 = sX + (aVec.i() * aSpeed);
	sY2 = sY + (aVec.j() * aSpeed);
	sZ2 = sZ + (aVec.k() * aSpeed);
	tX2 = tX + (tVec.i() * tSpeed);
	tY2 = tY + (tVec.j() * tSpeed);
	tZ2 = tZ + (tVec.k() * tSpeed);

	// Calculate vector to target after next cycle
	dx = tX2 - sX2;
	dy = tY2 - sY2;
	dz = tZ2 - sZ2;

	// Divide by distance to make a unit vector
	double dDistance2;
	dDistance2 = Dist3D(sX2, sY2, sZ2, tX2, tY2, tZ2);
	dx /= dDistance2;
	dy /= dDistance2;
	dz /= dDistance2;

	CHSVector nextVec(dx, dy, dz);

	// Calculate the dot product between the previous
	// and the next cycle vectors.
	double dp;
	dp = nowVec.DotProduct(nextVec);

	// Calculate the angle change.  This is in radians.
	dAngle = acos(dp);

	// Now divide angle change by 2pi to get change in angle
	// from 0 to 1, where 1 is a huge change in angle and,
	// therefore, high difficulty.
	dAngle *= .15915;

	// Add up to 6 points of defense for "evasion" by angle
	// change.
	iDefendRoll += (int) (6 * dAngle);


	// If distance is farther than our range, the shot always
	// misses.

	double range;
	range = GetRange();
				
	CHSUniverse *uDest;
	char tbuf[256];
	char fstat1[128];
	char fstat2[128];

	if (dDistance >= range || iDefendRoll > iAttackRoll) {
		sprintf(fstat1, "%s%smisses%s",ANSI_HILITE,ANSI_GREEN,ANSI_NORMAL);
		sprintf(fstat2, "%s%smissed%s",ANSI_HILITE,ANSI_GREEN,ANSI_NORMAL);
	} else {
		sprintf(fstat1, "%s%shits%s",ANSI_HILITE,ANSI_RED,ANSI_NORMAL);
		sprintf(fstat2, "%s%shit%s",ANSI_HILITE,ANSI_RED,ANSI_NORMAL);
	}
		
	uDest = uaUniverses.FindUniverse(cSource->GetUID());

	CHSSysSensors *cSensors;
	SENSOR_CONTACT *cContactS;
	SENSOR_CONTACT *cContactD;
	for (i = 0; i < HS_MAX_ACTIVE_OBJECTS; i++)
	{
		cCTarget = uDest->GetActiveUnivObject(i);
		if (!cCTarget)
			continue;
		if (cCTarget == cSource || cCTarget == cTarget)
			continue;

		cSensors = (CHSSysSensors *)cCTarget->GetEngSystem(HSS_SENSORS);
		if (!cSensors)
			continue;

		cContactS = cSensors->GetContact(cSource);
		cContactD = cSensors->GetContact(cTarget);


		if (!cContactS && !cContactD)
			continue;

		if (!cContactS && cContactD) {
			if (cContactD->status == DETECTED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - Unknown contact is being fired upon and %s",cTarget->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactD->m_id,ANSI_NORMAL,cTarget->GetObjectColor(),ANSI_NORMAL, fstat2);
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			} else if (cContactD->status == IDENTIFIED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - The %s is being fired upon and %s",cTarget->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactD->m_id,ANSI_NORMAL,cTarget->GetObjectColor(),ANSI_NORMAL, cSource->GetName(), fstat2);
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			}
			continue;
		}
						
											
		if (cContactS && !cContactD) {
			if (cContactS->status == DETECTED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - Unknown contact is firing upon something",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL);
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			} else if (cContactS->status == IDENTIFIED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - The %s is firing upon something",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL, cSource->GetName());
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			}
			continue;
		}

		if (cContactS && cContactD)
			if (cContactS->status == DETECTED && cContactD->status == DETECTED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - Unknown contact fires and %s unknown contact %s[%s%s%d%s%s]%s",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL, fstat1,cTarget->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactD->m_id,ANSI_NORMAL,cTarget->GetObjectColor(),ANSI_NORMAL);
				cCTarget->HandleMessage(tbuf,MSG_SENSOR, (long *)cCTarget);
			} else if (cContactS->status == IDENTIFIED && cContactD->status == IDENTIFIED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - The %s fires and %s the %s",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL, cSource->GetName(), fstat1, cTarget->GetName());
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			} else if (cContactS->status == IDENTIFIED && cContactD->status == DETECTED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - The %s fires and %s unknown contact %s[%s%s%d%s%s]%s",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL, cSource->GetName(), fstat1,cTarget->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactD->m_id,ANSI_NORMAL,cTarget->GetObjectColor(),ANSI_NORMAL);
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			} else if (cContactS->status == DETECTED && cContactD->status == IDENTIFIED) {
				sprintf(tbuf, "%s[%s%s%d%s%s]%s - Unknown contact fires and %s the %s",cSource->GetObjectColor(),ANSI_NORMAL,ANSI_HILITE,cContactS->m_id,ANSI_NORMAL,cSource->GetObjectColor(),ANSI_NORMAL, fstat1, cTarget->GetName());
				cCTarget->HandleMessage(tbuf, MSG_SENSOR, (long *)cCTarget);
			}

	}
	
	
	
	
	
	if (dDistance >= range)
    {
		if (dbUser != NOTHING)
			hsStdError(
			dbUser,
			"Your shot dissipates short of its target.");

		strcpy(tbuf,
			"An incoming energy shot has missed us.");
		cTarget->HandleMessage(tbuf, MSG_COMBAT, (long *)cSource);
	}
    else if (iAttackRoll > iDefendRoll)
	{
		// The weapon hits!
		// Determine strength based on base weapon
		// strength and range to target.
		int strength;

		strength = GetStrength();
		if (dDistance > (range * .333))
		{
			strength = (int)(strength * 
				(.333 + (1 - (dDistance / (range + .0001)))));
		}

		// If iSysType is not HSS_NOTYPE, then do a roll
		// against the accuracy of the weapon to see if
		// the system gets hit.
		if (iSysType != HSS_NOTYPE)
		{
			UINT ARoll, SRoll;
		
			ARoll = getrandom(GetAccuracy());
			SRoll = getrandom(10);

			if (SRoll > ARoll)
				iSysType = HSS_NOTYPE; // Didn't succeed
		}

		// Tell the target to take damage
		cTarget->HandleDamage(cSource, this, strength,
			cConsole, iSysType);
	
	}
	else
	{
		// The weapon misses. :(
		if (dbUser != NOTHING)
			hsStdError(dbUser,
			"Your shot skims past your target and out into space.");

		strcpy(tbuf,
			"An incoming energy shot has missed us.");
		cTarget->HandleMessage(tbuf, MSG_COMBAT, (long *)cSource);
	}

	Regenerate();
}