Defend_bsp()
============

Defend() - BEISPIELE
--------------------

FUNKTION
--------

     varargs int Defend(int dam, mixed dam_type, mixed spell, object enemy)

BEMERKUNGEN
-----------

     Die hier aufgefuehrten Komplexbeispiele sind zum Verstaendnis gedacht.

BEISPIELE
---------

  1) Ein ordinaerer Biss ins Bein.

     .. code-block:: pike

       this_player()->Defend(random(500),
                             ({DT_PIERCE, DT_RIP}),
                             0,
                             this_object());

  2) Ein Biss ins Bein, mit der Hose als 200%ige Ruestung und Rest mit 100%.

     .. code-block:: pike

       this_player()->Defend(random(500),
                             ({DT_PIERCE, DT_RIP}),
                             ([SP_PHYSICAL_ATTACK: 1,
                               SP_REDUCE_ARMOUR:   ([AT_TROUSERS: 200])
                             ]),
                             this_object());

  3) Der Biss, wenn ein Tier in die Hose gekrochen ist und dieser ohne
     Treffermeldung und physischen Ruestungsschutz durchgeht.

     .. code-block:: pike

       this_player()->Defend(random(500),
                             ({DT_PIERCE, DT_RIP}),
                             ([SP_PHYSICAL_ATTACK: 0, SP_SHOW_DAMAGE:0]),
                             this_object());

  4) Spell-Parameter
     Beispiel fuer einen Spell, der nur vom Helm normal und von einem
     Amulett mit 115% aufgehalten wird, alle anderen (angebenenen)
     Ruestungen haben 0% Schutzwirkung.
     Mit Ausgabe eigener Meldungen: beginnend mit -1, da der verursachte
     Schadenswert minimal 0 wird (fuers Ersetzen: Feind: @WEx2,
     Spieler: WEx1); maximal wird er (Empfindlichkeiten jetzt mal aussen
     vor) 49 (499/10 = 49), nicht 499!!!

     .. code-block:: pike

      this_player()->Defend(
       random(500),
       ({DT_PIERCE, DT_AIR}),
       ([SP_PHYSICAL_ATTACK: 1, // wegen DT_PIERCE
         SP_REDUCE_ARMOUR:   ([AT_ARMOUR:   0,
                               AT_HELMET: 100,
                               AT_RING:     0,
                               AT_GLOVE:    0,
                               AT_CLOAK:    0,
                               AT_BOOT:     0,
                               AT_TROUSERS: 0,
                               AT_SHIELD:   0,
                               AT_AMULET: 115,
                               AT_MISC:     0,
                               AT_BELT:     0,
                               AT_QUIVER:   0])
         SP_SHOW_DAMAGE:
               ({({-1,"@WER2 schrammt Dich mit einem durchbohrenden Blick.",
                      "Du schrammst @WEN1 mit einem durchbohrenden Blick.",
                      "@WER2 schrammt @WEN1 mit einem durchbohrenden Blick."
                 }),
                 ({5,"Der durchbohrende Blick von @WEM2 trifft Dich.",
                     "Dein durchbohrender Blick trifft @WEN1.",
                     "Der durchbohrende Blick von @WEM2 trifft @WEN1."
                 }),
                 ({20,"@WESSEN2 stechender Blick durchbohrt Dich.",
                      "Dein stechender Blick durchbohrt @WEN1.",
                      "@WESSEN2 stechender Blick durchbohrt @WEN1."
               })})
       ]),
       this_object());

     Etwas geschickter geht das Ganze, wenn wir einfach aus der Mudlib
     alle existierenden Ruestungen in ein Mapping packen und diese
     nullen (damit sind wir auch gegen neue Ruestungstypen sicher):

     .. code-block:: pike

       mapping amap = map_indices(VALID_ARMOUR_CLASS,#'!);
       amap[AT_HELMET]=100;
       amap[AT_AMULET]=115;

       this_player()->Defend(random(500),
                             ({DT_PIERCE, DT_AIR}),
                             ([SP_PHYSICAL_ATTACK: 1,
                               SP_REDUCE_ARMOUR: amap,
                               SP_SHOW_DAMAGE: ({ ... (siehe oben)

  5) Der Biss von weiter oben mit Meldung.
     Eine Meldung, die nur ausgegeben wird, wenn der Biss auch mindestens
     einen LP abzieht.

     .. code-block:: pike

       this_player()->Defend(random(500),
                             ({DT_PIERCE, DT_RIP}),
                             ([SP_PHYSICAL_ATTACK: 1,
                               SP_REDUCE_ARMOUR:   ([AT_TROUSERS: 200]),
                               SP_SHOW_DAMAGE: ({
                                 ({1,"@WER2 beisst Dich ins Bein!",
                                     "Du beisst @WEN1 ins Bein!",
                                     "@WER2 beisst @WEN1 ins Bein!"
                                  })           })
                             ]),
                             this_object());

  6) DefendFunc() und Defend() in einem Objekt

    a) eine Luftangriffe reflektierende Ruestung:

      .. code-block:: pike

        int DefendFunc(string *dtyp, mixed spell, object enemy) {
           if(member(dtyp, DT_AIR)>=0 && !spell[SP_RECURSIVE])
             enemy->Defend(random(200),
                           ({DT_AIR}),
                           ([SP_RECURSIVE: 1,
                             SP_SHOW_DAMAGE:
                             ({"Ein Luftwirbel erfasst auch Dich.",
                               "Deine Ruestung wirbelt @WEN1 herum.",
                               "@WESSEN2 Ruestung wirbelt @WEN1 herum."
                              })
                           ]),
                           QueryProp(P_WORN));

           return 0; // -> In diesem Fall gibts keinen Ruestungsbonus!
        }

    b) Eine NUR REINE Luftangriffe reflektierende Ruestung:

      .. code-block:: pike

        int DefendFunc(string *dtyp, mixed spell, object enemy) {
          if(!sizeof(dtyp-({DT_AIR})) && !spell[SP_RECURSIVE])
          ...

SIEHE AUCH
----------

  * Angriff:
    :doc:`Attack`, :doc:`do_damage`, :doc:`InsertEnemy`,
    :doc:`../props/P_NO_ATTACK`

  * Schaden:
    :doc:`reduce_hit_points`, :doc:`reduce_spell_points`,
    :doc:`../props/P_ENABLE_IN_ATTACK_OUT`, :doc:`../props/P_LAST_MOVE`

  * Schutz:
    :doc:`InformDefend`, :doc:`DefendOther`, :doc:`QueryDefend`,
    :doc:`Defend`,
    :doc:`../props/P_DEFENDERS`, :doc:`../props/P_ARMOURS`,
    :doc:`../props/P_AC`, :doc:`../props/P_DEFEND_FUNC`,
    :doc:`../props/P_BODY`

  * Resistenz:
    :doc:`CheckResistance`, :doc:`../props/P_RESISTANCE_STRENGTHS`

  * Daten:
    :doc:`../props/P_LAST_COMBAT_TIME`, :doc:`../props/P_LAST_XP`,
    :doc:`../props/P_LAST_DAMAGE`, :doc:`../props/P_LAST_DAMTYPES`,
    :doc:`../props/P_LAST_DAMTIME`

  * Sonstiges
    :doc:`CheckSensitiveAttack`, :doc:`UseSkill`, :doc:`InternalModifyDefend`

23.01.2020 Zesstra
