// Called every frame
void AMissleProjectile::Tick( float DeltaTime )
{
	Super::Tick(DeltaTime);

		if (TargetActor != nullptr)
		{
			NotifyTarget(this);

			FVector WantedDir = (TargetActor->GetActorLocation() - GetActorLocation()).GetSafeNormal();
			WantedDir += TargetActor->GetVelocity() * WantedDir.Size() / MissleMovement->MaxSpeed;
			
			MissleMovement->Velocity += WantedDir * MissleMovement->InitialSpeed * 100.0f * DeltaTime;
			MissleMovement->Velocity = MissleMovement->Velocity.GetSafeNormal() * MissleMovement->MaxSpeed;

			FVector Dis = GetActorLocation() - (TargetActor->GetActorLocation());
			if (Dis.Size() < 5)
			{
				Server_Explode(TargetActor, BP_Explosion.GetDefaultObject(), Damage);
			}
		}
		else
		{
			NotifyTarget(nullptr);
			SetLifeSpan(1.0f);
		}
}
Example #2
0
void Slider::MessageReceived (BMessage *message)
{
	switch (message->what)
	{
	case 'tcVC':
	{
		float tv = 0;
		if (tc)
		{
			tv = atof (tc->Text());
			if (tv < min) tv = min;
			if (tv > max) tv = max;
			if (step > 1 && fmod (tv - min, step))
				tv = int ((tv - min)/step)*step + min;
			if (fmt[strlen (fmt) - 2] == '0')
				tv = int (tv + 0.5);
			RemoveChild (tc);
		}
		delete tc;
		tc = NULL;
		SetValue (tv);
		NotifyTarget();
		break;
	}
	default:
		// message->PrintToStream();
		inherited::MessageReceived (message);
	}
}
Example #3
0
void Slider::KeyDown (const char *bytes, int32 numBytes)
{
	if (numBytes == 1)
	{
		switch (*bytes)
		{
		case B_ESCAPE:
		{
			if (tc)
			{
				// printf ("TextControl is open\n");
				RemoveChild (tc);
				delete (tc);
				tc = NULL;
			}
			break;
		}
		case B_SPACE:
		case B_ENTER:
		{	
			//printf ("Enter\n");
			if (tc)
			{
				// printf ("TextControl is open\n");
				BMessage *key = new BMessage ('tcVC');
				MessageReceived (key);
				delete key;
			}
			else
			{
				knobpos = BPoint (float (value - min)/(max - min)*(width - knobsize), 1);
				BRect kbr = BRect (knobpos.x + sep, knobpos.y, knobpos.x + knobsize - 2 + sep, knobpos.y + height - 3);
		//		kbr.PrintToStream();
				tc = new BTextControl (kbr, "slider value field", "", "", new BMessage ('tcVC'));
				tc->SetTarget (this);
				tc->SetDivider (0);
				EnterFilter *filter = new EnterFilter (this);
				tc->TextView()->AddFilter (filter);
				char vs[64];
				sprintf (vs, fmt, value);
				tc->SetText (vs);
				AddChild (tc);
				tc->MakeFocus (true);
				inherited::KeyDown (bytes, numBytes);
			}
			break;
		}
		case B_LEFT_ARROW:
			//printf ("Left\n");
			if (value > min)
			{
				value -= step;
				Invalidate();
				NotifyTarget();
			}
			break;
		case B_RIGHT_ARROW:
			//printf ("Right\n");
			if (value < max)
			{
				value += step;
				Invalidate();
				NotifyTarget();
			}
			break;
		case B_TAB:
			// printf ("Tab\n");
			if (tc)
			{
				// printf ("TextControl is open\n");
				BMessage *key = new BMessage ('tcVC');
				MessageReceived (key);
				delete key;
			}
			else
			{
			// MakeFocus (false);
				inherited::KeyDown (bytes, numBytes);
				Invalidate();
				break;
			}
		default:
			inherited::KeyDown (bytes, numBytes);
		}
	}
	else
		inherited::KeyDown (bytes, numBytes);
}
Example #4
0
void Slider::MouseDown (BPoint point)
// Note: Still assumes horizontal slider ATM!
{
	if (tc)	// TextControl still visible...  Block other mouse movement.
		return;
		
	BPoint knobpos = BPoint (float (value - min)/(max - min)*(width - knobsize), 1);
	knob = BRect (knobpos.x + 1, knobpos.y + 1, knobpos.x + knobsize - 2, knobpos.y + height - 2);
	ulong buttons;
	buttons = Window()->CurrentMessage()->FindInt32 ("buttons");
	float px = -1;
	bool dragging = false;
	if (click != 2 && buttons & B_PRIMARY_MOUSE_BUTTON && !(modifiers() & B_CONTROL_KEY))
	{
		BPoint bp, pbp;
		uint32 bt;
		GetMouse (&pbp, &bt, true);
		bigtime_t start = system_time();
		if (knob.Contains (BPoint (pbp.x - sep, pbp.y)))
		{
			while (system_time() - start < dcspeed)
			{
				snooze (20000);
				GetMouse (&bp, &bt, true);
				if (!bt && click != 2)
				{
					click = 0;
				}
				if (bt && !click)
				{
					click = 2;
				}
				if (bp != pbp)
					break;
			}
		}
		if (click != 2)
		{
			// Now we're dragging...
			while (buttons)
			{
				BPoint p = BPoint (point.x - sep, point.y);
				float x = p.x;
				if (!(knob.Contains (p)) && !dragging)
				{
					if (x > knob.left)
					{
						value += step * (x - knob.right)/10;
					}
					else
					{
						value += step * (x - knob.left)/10;
					}
					if (value < min)
						value = min;
					if (value > max)
						value = max;
					if (step > 1 && fmod (value - min, step))	// Hack hack!
						value = int ((value - min)/step)*step + min;
		//			if (fmt[strlen (fmt) - 2] == '0')
		//				value = int (value + 0.5);
					offslid->Lock();
					Invalidate (BRect (sep + 1, 0, offslid->Bounds().Width() + sep, height));
					offslid->Unlock();
					NotifyTarget();
				}
				else if (px != p.x && step <= 1)	// Hacks galore!
				{
					dragging = true;
					value = (x - knobsize/2) / (width - knobsize) * (max - min) + min;
					//printf ("x = %f, knobsize = %f, value = %f\n", x, knobsize, value);
					//printf ("Value: %f ", value);
					if (value < min)
						value = min;
					if (value > max)
						value = max;
					if (step > 1 && fmod (value - min, step))
						value = int ((value - min)/step)*step + min;
					if (fmt[strlen (fmt) - 2] == '0')
						value = int (value + 0.5);
					//printf ("-> %f\n", value);
					offslid->Lock();
					Invalidate (BRect (sep + 1, 0, offslid->Bounds().Width() + sep, height));
					offslid->Unlock();
					px = p.x;
					NotifyTarget();
				}
				knobpos = BPoint (float (value - min)/(max - min)*(width - knobsize), 1);
				knob = BRect (knobpos.x + 1, knobpos.y + 1, knobpos.x + knobsize - 2, knobpos.y + height - 2);
				snooze (20000);
				GetMouse (&point, &buttons, true);
			}
			click = 1;
		}
	}
	if (click == 2 || buttons & B_SECONDARY_MOUSE_BUTTON || modifiers() & B_CONTROL_KEY)
	{
		click = 1;
		if (tc)
		{
			RemoveChild (tc);
			delete tc;
		}
		knobpos = BPoint (float (value - min)/(max - min)*(width - knobsize), 1);
		BRect kbr = BRect (knobpos.x + sep, knobpos.y, knobpos.x + knobsize - 2 + sep, knobpos.y + height - 3);
//		kbr.PrintToStream();
		tc = new BTextControl (kbr, "slider value field", "", "", new BMessage ('tcVC'));
		tc->SetTarget (this);
		tc->SetDivider (0);
		EnterFilter *filter = new EnterFilter (this);
		tc->TextView()->AddFilter (filter);
		char vs[64];
		sprintf (vs, fmt, value);
		tc->SetText (vs);
		AddChild (tc);
		tc->MakeFocus (true);
	}
	NotifyTarget ();
}
void CombatManager::ApplyCombatEvent(psCombatGameEvent *event, int attack_result)
{
    psCharacter *attacker_data = event->GetAttackerData();
    psCharacter *target_data=event->GetTargetData();

    MathVar *weaponDecay = NULL;
    MathVar *blockDecay = NULL;
    MathVar *armorDecay = NULL;
    MathEnvironment env;

    psItem *weapon         = attacker_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot());
    psItem *blockingWeapon = target_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot(),true);
    psItem *struckArmor    = target_data->Inventory().GetEffectiveArmorInSlot(event->AttackLocation);

    // there may only be a decay if you actually hit your target by some means
    if(attack_result == ATTACK_DAMAGE || attack_result == ATTACK_BLOCKED)
    {
        // we are guaranteed some armor is present - real one, race one or base one
        CS_ASSERT(struckArmor);
        float ArmorVsWeapon = weapon->GetArmorVSWeaponResistance(struckArmor->GetBaseStats());

        // clamp value between 0 and 1
        ArmorVsWeapon = ArmorVsWeapon > 1.0F ? 1.0F : ArmorVsWeapon < 0.0F ? 0.0F : ArmorVsWeapon;

        env.Define("Weapon", weapon);                             // weapon that was used to attack
        env.Define("BlockingWeapon", blockingWeapon);             // weapon that blocked the attack
        env.Define("Armor", struckArmor);                         // armor hit
        env.Define("ArmorVsWeapon", ArmorVsWeapon);               // armor vs weapon effectiveness
        env.Define("Damage", event->FinalDamage);                 // actual damage dealt
        env.Define("Blocked", (attack_result == ATTACK_BLOCKED)); // identifies whether this attack was blocked

        calc_decay->Evaluate(&env);

        weaponDecay = env.Lookup("WeaponDecay");
        blockDecay  = env.Lookup("BlockingDecay");
        armorDecay  = env.Lookup("ArmorDecay");
    }

    gemActor *gemAttacker = dynamic_cast<gemActor*> ((gemObject *) event->attacker);
    gemActor *gemTarget   = dynamic_cast<gemActor*> ((gemObject *) event->target);

    switch (attack_result)
    {
        case ATTACK_DAMAGE:
        {
            bool isNearlyDead = false;
            if (target_data->GetMaxHP().Current() > 0.0 && target_data->GetHP()/target_data->GetMaxHP().Current() > 0.2)
            {
                if ((target_data->GetHP() - event->FinalDamage) / target_data->GetMaxHP().Current() <= 0.2)
                    isNearlyDead = true;
            }

            psCombatEventMessage ev(event->AttackerCID,
                isNearlyDead ? psCombatEventMessage::COMBAT_DAMAGE_NEARLY_DEAD : psCombatEventMessage::COMBAT_DAMAGE,
                gemAttacker->GetEID(),
                gemTarget->GetEID(),
                event->AttackLocation,
                event->FinalDamage,
                weapon->GetAttackAnimID(gemAttacker->GetCharacterData()),
                gemTarget->FindAnimIndex("hit"));

            ev.Multicast(gemTarget->GetMulticastClients(),0,MAX_COMBAT_EVENT_RANGE);

            // Apply final damage
            if (target_data!=NULL)
            {
                gemTarget->DoDamage(gemAttacker,event->FinalDamage);
                
                if (gemAttacker)
                {
                    gemAttacker->InvokeAttackScripts(gemTarget, weapon);
                }

                if (gemTarget)
                {
                    gemTarget->InvokeDefenseScripts(gemAttacker, weapon);
                    if(isNearlyDead)
                    {
                        gemTarget->InvokeNearlyDeadScripts(gemAttacker, weapon);
                    }
                }
            }

            // If the target wasn't in combat, it is now...
            // Note that other modes shouldn't be interrupted automatically
            if (gemTarget->GetMode() == PSCHARACTER_MODE_PEACE || gemTarget->GetMode() == PSCHARACTER_MODE_WORK)
            {
                if (gemTarget->GetClient())  // Set reciprocal target
                    gemTarget->GetClient()->SetTargetObject(gemAttacker,true);

                // The default stance is 'Fully Defensive'.
                Stance initialStance = GetStance(cacheManager, "FullyDefensive");
                AttackSomeone(gemTarget,gemAttacker,initialStance);
            }

            if (weapon)
            {
                weapon->AddDecay(weaponDecay->GetValue());
            }
            if (struckArmor)
            {
                struckArmor->AddDecay(armorDecay->GetValue());
            }

            NotifyTarget(gemAttacker,gemTarget);

            break;
        }
        case ATTACK_DODGED:
        {
            psCombatEventMessage ev(event->AttackerCID,
                psCombatEventMessage::COMBAT_DODGE,
                gemAttacker->GetEID(),
                gemTarget->GetEID(),
                event->AttackLocation,
                0, // no dmg on a dodge
                weapon->GetAttackAnimID(gemAttacker->GetCharacterData()),
                (unsigned int)-1); // no defense anims yet

            ev.Multicast(gemTarget->GetMulticastClients(),0,MAX_COMBAT_EVENT_RANGE);
            NotifyTarget(gemAttacker,gemTarget);
            break;
        }
        case ATTACK_BLOCKED:
        {
            psCombatEventMessage ev(event->AttackerCID,
                psCombatEventMessage::COMBAT_BLOCK,
                gemAttacker->GetEID(),
                gemTarget->GetEID(),
                event->AttackLocation,
                0, // no dmg on a block
                weapon->GetAttackAnimID( gemAttacker->GetCharacterData() ),
                (unsigned int)-1); // no defense anims yet

            ev.Multicast(gemTarget->GetMulticastClients(),0,MAX_COMBAT_EVENT_RANGE);

            if (weapon)
            {
                weapon->AddDecay(weaponDecay->GetValue());
            }
            if (blockingWeapon)
            {
                blockingWeapon->AddDecay(blockDecay->GetValue());
            }

            NotifyTarget(gemAttacker,gemTarget);

            break;
        }
        case ATTACK_MISSED:
        {
            psCombatEventMessage ev(event->AttackerCID,
                psCombatEventMessage::COMBAT_MISS,
                gemAttacker->GetEID(),
                gemTarget->GetEID(),
                event->AttackLocation,
                0, // no dmg on a miss
                weapon->GetAttackAnimID( gemAttacker->GetCharacterData() ),
                (unsigned int)-1); // no defense anims yet

            ev.Multicast(gemTarget->GetMulticastClients(),0,MAX_COMBAT_EVENT_RANGE);
            NotifyTarget(gemAttacker,gemTarget);
            break;
        }
        case ATTACK_OUTOFRANGE:
        {
            if (event->AttackerCID)
            {
                psserver->SendSystemError(event->AttackerCID,"You are too far away to attack!");

                // Auto-stop attack is commented out below, when out of range to prevent npc kiting by jumping in and out of range
                //if (event->attacker && event->attacker.IsValid())
                //    StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker));  // if you run away, you exit attack mode
            }
            break;
        }
        case ATTACK_BADANGLE:
        {
            if (event->AttackerCID)  // if human player
            {
                psserver->SendSystemError(event->AttackerCID,"You must face the enemy to attack!");

                // Auto-stop attack is commented out below, when out of range to prevent npc kiting by jumping in and out of range
                //if (event->attacker && event->attacker.IsValid())
                //    StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker));  // if you run away, you exit attack mode
            }
            break;
        }
        case ATTACK_OUTOFAMMO:
        {
            psserver->SendSystemError(event->AttackerCID, "You are out of ammo!");

            if (event->attacker && event->attacker.IsValid())
                StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker));  // if you run out of ammo, you exit attack mode
            break;
        }
    }
}