Author Topic: Weapon damage outside of minigames  (Read 1799 times)

I am making an RPG that does not take place inside a minigame. This is to prevent players from damaging other players (or NPC's).

I need to enable damage to and from bots in certain situations, I.e. when fighting monsters. The most practical way to achieve this would be to check the vehicle name on the monster's vehicle spawn brick(not the datablock UIName, since the datablock will vary), and allow damage to occur if the vehicle name is "Monster".

However, I am nearly blank on what to do, so I ask of you to give me a hand or just some starting pointers. :)
« Last Edit: April 26, 2011, 12:17:51 PM by Jorgur »

use trace(1) when you shoot at something inside a minigame, and outside a minigame
this should show you where the differences are.

Your solution to disable weapon damage is like me saying: "I don't want to go through Airport Security to use an airplane, so I'm going to mutate my body into a bird so I can just fly there myself. However, I am nearly blank on what to do, so I ask of you to give me a hand or just some starting pointers. :)"

Idea: Use a minigame and overwrite miniGameCanDamage.

use trace(1) when you shoot at something inside a minigame, and outside a minigame
this should show you where the differences are.

Ok, will try that.

Your solution to disable weapon damage is like me saying: "I don't want to go through Airport Security to use an airplane, so I'm going to mutate my body into a bird so I can just fly there myself. However, I am nearly blank on what to do, so I ask of you to give me a hand or just some starting pointers. :)"
If it can be done, I will do it.

Obviously it can be done, you're just going at it in the least logical or practical manner imaginable.

I did a trace in 3 different cases and came up with 2 possible solutions. Now, I have some questions:
- Which solution would be best to use?
- Would you recommend any other solutions?
- I need to take a look at the functions I want to overwrite. How can I find them?

Case 1:
I attacked someone else's horse outside of minigame. No damage occurred.
My goal is to enable damage in this case (under certain conditions).

Case 2:
I attacked my own horse outside of minigame. Damage occurred, even though MinigameCanDamage returned -1.
This behaviour could be mimicked and applied to case 1.

Case 3:
I attacked my own horse inside a minigame with weapon damage on. MinigameCanDamage returned 1, so damage occurred.

Solution 1
Modify MinigameCanDamage to return 1 when certain conditions are met.
A simple solution, but it would seem a bit hacky, since everything happens outside of minigame.

Solution 2
Modify ProjectileData::onCollision to call ProjectileData::Damage when certain conditions are met.
Less hacky solution. As seen in case 2, Blockland already does this when attacking your own bot outside of minigame.


Trace:
Passworded internet server
199: My Blockland ID
4382: Someone else's ID
Code: [Select]
CASE 1
ATTACKING SOMEONE ELSE'S HORSE
OUTSIDE OF MINIGAME
Entering ProjectileData::onCollision(849, 73697, 73654, 1, 288.526367 0.250000 120.277847, 0.000000 1.000000 0.000000, -0.615194 -79.777100 -11.420200)
   Entering getBL_IDFromObject(73697)
      Entering getBrickGroupFromObject(73697)
      Leaving getBrickGroupFromObject() - return 41197
   Leaving getBL_IDFromObject() - return 199
   Entering miniGameCanDamage(41190, 73654)
      Entering getMiniGameFromObject(41190)
      Leaving getMiniGameFromObject() - return -1
      Entering getMiniGameFromObject(73654)
         Entering SimGroup::getClient(42330)
         Leaving SimGroup::getClient() - return 0
      Leaving getMiniGameFromObject() - return -1
   Leaving miniGameCanDamage() - return -1
Leaving ProjectileData::onCollision() - return -1

CASE 2
ATTACKING OWN HORSE
OUTSIDE OF MINIGAME
Entering ProjectileData::onCollision(849, 73705, 73652, 1, 293.442688 0.250000 120.283272, 0.000000 1.000000 0.000000, -0.619024 -80.273804 -11.491300)
   Entering getBL_IDFromObject(73705)
      Entering getBrickGroupFromObject(73705)
      Leaving getBrickGroupFromObject() - return 41197
   Leaving getBL_IDFromObject() - return 199
   Entering miniGameCanDamage(41190, 73652)
      Entering getMiniGameFromObject(41190)
      Leaving getMiniGameFromObject() - return -1
      Entering getMiniGameFromObject(73652)
         Entering SimGroup::getClient(41197)
         Leaving SimGroup::getClient() - return 41190
         Entering SimGroup::getClient(41197)
         Leaving SimGroup::getClient() - return 41190
      Leaving getMiniGameFromObject() - return -1
   Leaving miniGameCanDamage() - return -1
   Entering ProjectileData::Damage(849, 73705, 73652, 1, 293.442688 0.250000 120.283272, 0.000000 1.000000 0.000000)
      Entering ShapeBase::Damage(73652, 73705, 293.442688 0.250000 120.283272, 35, 10)
         Entering Armor::Damage(855, 73652, 73705, 293.442688 0.250000 120.283272, 35, 10)
            Entering Armor::onDamage(855, 73652, 35.000000)
               Entering Player::playPain(73652)
               Leaving Player::playPain() - return 855
            Leaving Armor::onDamage() - return 855
            Entering Player::emote(73652, PainMidImage, 1)
            Leaving Player::emote() - return 73652
         Leaving Armor::Damage() - return 73652
      Leaving ShapeBase::Damage() - return 73652
   Leaving ProjectileData::Damage() - return 73652
   Entering ProjectileData::impactImpulse(849, 73705, 73652, -0.619024 -80.273804 -11.491300)
   Leaving ProjectileData::impactImpulse() - return 218836
Leaving ProjectileData::onCollision() - return 218836

CASE 3
ATTACKING OWN HORSE
INSIDE MINIGAME
Entering ProjectileData::onCollision(849, 73765, 73744, 1, 293.506836 0.250000 120.421066, 0.000000 1.000000 0.000000, 3.230390 -76.527901 -6.085890)
   Entering getBL_IDFromObject(73765)
      Entering getBrickGroupFromObject(73765)
      Leaving getBrickGroupFromObject() - return 41197
   Leaving getBL_IDFromObject() - return 199
   Entering miniGameCanDamage(41190, 73744)
      Entering getMiniGameFromObject(41190)
      Leaving getMiniGameFromObject() - return 73717
      Entering getMiniGameFromObject(73744)
         Entering SimGroup::getClient(41197)
         Leaving SimGroup::getClient() - return 41190
         Entering SimGroup::getClient(41197)
         Leaving SimGroup::getClient() - return 41190
      Leaving getMiniGameFromObject() - return 73717
   Leaving miniGameCanDamage() - return 1
   Entering ProjectileData::Damage(849, 73765, 73744, 1, 293.506836 0.250000 120.421066, 0.000000 1.000000 0.000000)
      Entering ShapeBase::Damage(73744, 73765, 293.506836 0.250000 120.421066, 35, 10)
         Entering Armor::Damage(855, 73744, 73765, 293.506836 0.250000 120.421066, 35, 10)
            Entering Armor::onDamage(855, 73744, 35.000000)
               Entering Player::playPain(73744)
               Leaving Player::playPain() - return 855
            Leaving Armor::onDamage() - return 855
            Entering Player::emote(73744, PainMidImage, 1)
            Leaving Player::emote() - return 73744
         Leaving Armor::Damage() - return 73744
      Leaving ShapeBase::Damage() - return 73744
   Leaving ProjectileData::Damage() - return 73744
   Entering ProjectileData::impactImpulse(849, 73765, 73744, 3.230390 -76.527901 -6.085890)
   Leaving ProjectileData::impactImpulse() - return 237494
Leaving ProjectileData::onCollision() - return 237494

« Last Edit: April 26, 2011, 02:02:56 PM by Jorgur »

Solution 2
Modify ProjectileData::onCollision to call ProjectileData::Damage when certain conditions are met.
Less hacky solution. As seen in case 2, Blockland already does this when attacking your own bot outside of minigame.
I would not reccomend this solution.  When you shoot with the rocket launcher or tank turret, or anything that does AOE damage, then you also need to modify Projectile::onExplode, and addon with its own ::onExplode will cause problems.  You will also have problems with the blast throwing players around, even if it doesnt do any damage.

Suggested solution:
1)  Always use a minigame.
2) RE-write (not override)  MinigameCanDamage to use whatever conditions you want.
     - this means you never call "Parent" in your version of the function.

3) use bots with care

Solution 1
Modify MinigameCanDamage to return 1 when certain conditions are met.
A simple solution, but it would seem a bit hacky, since everything happens outside of minigame.
Why don't you simply do this in a minigame? If you need an example of a minigame that doesn't need an owner and starts automatically, look here, although that's a pretty bad one.