Saltar al contenido

Más en DLAN: Nuestras Traducciones | Otras Traducciones | Mods y modding | Revisiones y Guías | Videojuegos | Arte | Literatura | Rol y Rol por foro e IRC | Mapa de la web
Foto

Areas de Efecto General Configurables

avernum Tierra de Heroes scripting

2 respuestas al tema

#1 Avernum

Avernum

    Humano

  • Miembro
  • Pip
  • 14 posts

Posteado 02 May 2020 - 01:16 PM

Hola, 

 

Os presento un sistema para crear fácilmente lo que llamo Areas de Efecto, versión 1.0 Beta.

 

Consiste en un trigger y opcionalmente un ubicado controlador que aplican efectos a los personajes o criaturas que se encuentran dentro de dicho trigger, o lo cruzan, todo ello con 3 scripts.

 

El trigger aplica un efecto (entre 40 ahora mismo) que dura mientras estés dentro del trigger, opcionalmente afecta a criaturas no jugadoras y también opcionalmente permite configurar un objeto que te libra del daño (por ejemplo una gema de protección contra el mal o un casco de respirar bajo el agua) . Puedes configurar que este objeto deba estar equipado o simplemente vale con que esté en tu inventario.

 

Opcionalmente aplica un efecto visual al entrar y salir y otro mientras estés dentro del trigger.

 

Opcionalmente muestra un texto al entrar o salir del trigger (¡El aire de aquí me quema los pulmones!.... Ya se respira mejor)

 

Ejemplos de uso: 

 

-Aplicar efecto de daño por fuego cada tanto tiempo si tu personaje se acerca al borde de un río de lava.

-Aplicar daño por ácido al permanecer en una habitación con atmósfera envenenada.

-Aplicar daño por frío y efecto de reducción de velocidad al estar bajo el agua, con efecto de burbujas)

-Aplicar en resumen cada uno de los tipos de daño, con efecto de daño (ejemplo 2d6), efecto visual y frase opcional al recibir daño (Ay ay, coff coff)

-Bonus a la armadura por cobertura.

-Zona santuario (¡Estoy en casa, no me puedes hacer nada!) 

-Zona de magia muerta, que impide lanzar todos los hechizos, o solo de tal escuela (¡En el templo de Iuz no puedes lanzar curaciones!)

-Barrera antihechizos, que disipa toda tu magia o todos los hechizos hasta tal nivel.

-Zona de terreno dificil, que dificulta movimiento.

-Zona de alta velocidad --> como una cinta transportadora!

-Zona de polimorfizacion (para aventuras en las que te conviertes en pollo o rata o lo que sea para pasar desapercibido, o como broma o como trampa)

-Incrementar ataques, maximo 5 por turno por limitacion de motor.

-Zonas elementales (ejemplo Plano del Aire: daño incrementado electrico, no puedes usar hechizos de fuego, mas velocidad)

-Zona de bonus al ataque por ventaja, por ejemplo zona alta vs zona baja

-Apresurar, Enlentecer

-Reduccion de daño

-Resistencia a la magia

-Así hasta 40 efectos en esta versión

 

Fácilmente configurable por variables que se ponen en el trigger y si usas ubicado controlador en el controlador.

 

Optimizado para no requerir mucha CPU, en el caso de daño por tiempo.

 

El efecto se puede desactivar. Al usar una palanca desaparecen los vapores, etc etc.

 

Ver el módulo de ejemplo para ver cómo se configura y haceros una idea de los usos.

 

Scripts: 

 

On Enter del Trigger

 

//::///////////////////////////////////////////////
//:: TIERRA DE HEROES - oe_area_efecto
//:: Copyright (c) 2018 Fran Luque (Avernum).
//:://////////////////////////////////////////////
/*
    oe_area_efecto
    oh_area_efecto
    ox_area_efecto
*/
//:://////////////////////////////////////////////
//:: Created By: Fran Luque
//:: Created On: 12/05/2018
//:: Last Updated: 01/05/2020
//:://////////////////////////////////////////////
void main()
{
    //if (GetLocalInt(OBJECT_SELF, "AreaDesactivada")==TRUE){return;}

    object oPC          = GetEnteringObject();
    string sFraseEnter  = GetLocalString(OBJECT_SELF,"FraseEnter");
    int iEfectoSobrePJ  = GetLocalInt(OBJECT_SELF,   "EfectoSobrePJ");
    int iFX             = GetLocalInt(OBJECT_SELF,   "FXPermanente");
    int iFXInstant      = GetLocalInt(OBJECT_SELF,   "FXInstant");
    int iParam1         = GetLocalInt(OBJECT_SELF,   "Parametro1");
    int iParam2         = GetLocalInt(OBJECT_SELF,   "Parametro2");
    int iParam3         = GetLocalInt(OBJECT_SELF,   "Parametro3");
    string sMiTag       = GetTag(OBJECT_SELF);
    effect eEfectoPJ;
    effect eFX;
    effect eFXInstant;

    if (GetLocalInt(OBJECT_SELF,"AfectaEnemigos")==FALSE)
    {
        if (!GetIsPC(oPC)) return;
    }

    SetLocalInt (oPC, "EfectoAreaEfecto"+sMiTag, GetTimeSecond() + 1);

    //Efectos mientras estes en el area de efecto, independientes de oh_area_efecto
    //EffectSlow
    //EffectBlindness
    //EffectCurse
    //EffectConcealment(50,MISS_CHANCE_TYPE_NORMAL);
    //EffectDarkness
    //EffectMovementSpeedDecrease(porcentaje);
    //EffectMovementSpeedIncrease(porcentaje);
    //EffectRegenerate(cantidad, cadaxsegundos);
    //EffectSanctuary(dc);
    //EffectSpellFailure(porcentaje,SPELL_SCHOOL_GENERAL);
    //Dispel
    //Polymorph
    //Swarm ATENCION: Los bichos swarmeados seran parte de la party del pj , o sea sus colegas
    if (iEfectoSobrePJ!=0)
    {
        switch(iEfectoSobrePJ)
        {
            case 1:  eEfectoPJ = EffectSlow(); break;
            case 2:  eEfectoPJ = EffectBlindness(); break;
            case 3:  eEfectoPJ = EffectCurse(); break;
            case 4:  eEfectoPJ = EffectConcealment(iParam1, iParam2); break;  //50,MISS_CHANCE_TYPE_NORMAL
            case 5:  eEfectoPJ = EffectDarkness(); break;
            case 6:  eEfectoPJ = EffectMovementSpeedIncrease(iParam1); break;    //Porcentaje
            case 7:  eEfectoPJ = EffectMovementSpeedDecrease(iParam1); break;    //Porcentaje
            case 8:  eEfectoPJ = EffectRegenerate(iParam1, 1.0f); break;   //Cantidad por segundo
            case 9:  eEfectoPJ = EffectSanctuary(iParam1); break;    //DC
            case 10: eEfectoPJ = EffectSpellFailure(iParam1, iParam2); break; //100(porcentaje),SPELL_SCHOOL_GENERAL
            case 11: eEfectoPJ = EffectDispelMagicAll(iParam1); break;  //Nivel
            case 12: eEfectoPJ = EffectPolymorph(iParam1, TRUE); break;  //POLYMORPH_TYPE_CHICKEN
            case 13: eEfectoPJ = EffectSwarm(TRUE, "zep_skeldolls", "zep_skeldwarf", "zep_skeldolls", "zep_skeldwarf"); break;
            case 14: eEfectoPJ = EffectHaste(); break;
            case 15: eEfectoPJ = EffectTrueSeeing(); break;
            case 16: eEfectoPJ = EffectDamageIncrease(iParam1, iParam2); break;  //int nBonus, int nDamageType=DAMAGE_TYPE_MAGICAL
            case 17: eEfectoPJ = EffectDamageDecrease(iParam1, iParam2); break;  //int nPenalty, int nDamageType=DAMAGE_TYPE_MAGICAL
            case 18: eEfectoPJ = EffectDamageImmunityIncrease(iParam1, iParam2); break;  //DAMAGE_TYPE_MAGICAL, 50
            case 19: eEfectoPJ = EffectDamageImmunityDecrease(iParam1, iParam2); break;  //DAMAGE_TYPE_MAGICAL, 50
            case 20: eEfectoPJ = EffectNegativeLevel(iParam1); break; //Niveles
            case 21: eEfectoPJ = EffectTemporaryHitpoints(iParam1); break; //HP
            case 22: eEfectoPJ = EffectSpellResistanceIncrease(iParam1); break;  //Cantidad
            case 23: eEfectoPJ = EffectSpellResistanceDecrease(iParam1); break;  //Cantidad
            case 24: eEfectoPJ = EffectAbilityIncrease(iParam1, iParam2); break;  //ABILITY_CONSTITUTION,6
            case 25: eEfectoPJ = EffectAbilityDecrease(iParam1, iParam2); break;  //ABILITY_CONSTITUTION,6
            case 26: eEfectoPJ = EffectSavingThrowIncrease(iParam1, iParam2); break;  //SAVING_THROW_ALL,5
            case 27: eEfectoPJ = EffectSavingThrowDecrease(iParam1, iParam2); break; //SAVING_THROW_ALL,5
            case 28: eEfectoPJ = EffectACIncrease(iParam1); break;    //Cantidad CA
            case 29: eEfectoPJ = EffectACDecrease(iParam1); break;    //Cantidad CA
            case 30: eEfectoPJ = EffectAttackIncrease(iParam1); break;    //Cantidad bonus ataques
            case 31: eEfectoPJ = EffectAttackDecrease(iParam1); break;    //Cantidad bonus ataques
            case 32: eEfectoPJ = EffectSkillIncrease(iParam1, iParam2); break; //SKILL_CONCENTRATION,5
            case 33: eEfectoPJ = EffectSkillDecrease(iParam1, iParam2); break; //SKILL_CONCENTRATION,5
            case 34: eEfectoPJ = EffectDamageReduction(iParam1, iParam2); break; //10/+4 por ejemplo
            case 35: eEfectoPJ = EffectDamageResistance(iParam1, iParam2); break;    //DAMAGE_TYPE_MAGICAL, 10
            case 36: eEfectoPJ = EffectDamageShield(iParam1, iParam2, iParam3); break; //5, DAMAGE_BONUS_*, DAMAGE_TYPE_*
            case 37: eEfectoPJ = EffectImmunity(iParam1); break;     //IMMUNITY_TYPE_*
            case 38: eEfectoPJ = EffectMissChance(iParam1); break;   //Porcentaje fallo
            case 39: eEfectoPJ = EffectModifyAttacks(iParam1); break; //5 max
            case 40: eEfectoPJ = EffectSpellImmunity(iParam1); break;  //SPELL_* o -1 para todos
        }
        eEfectoPJ = TagEffect(eEfectoPJ, "EfectoAreaEfecto"+sMiTag);
        eEfectoPJ = SupernaturalEffect(eEfectoPJ);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEfectoPJ, oPC);
    }

    //FX mientras estes en area de efecto (VFX_DUR)
    if (iFX!=0)
    {
        eFX = EffectVisualEffect(iFX);
        eFX = TagEffect(eFX, "EfectoAreaEfecto"+sMiTag);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eFX, oPC);
    }

    //FX instantaneo al entrar en la zona (VFX_FNF, VFX_IMP, VFX_COM
    if (iFXInstant!=0)
    {
        eFXInstant = EffectVisualEffect(iFXInstant);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eFXInstant, oPC);
    }

    //Texto informativo al entrar en el trigger
    if (sFraseEnter!=""){FloatingTextStringOnCreature(sFraseEnter, oPC, FALSE);}
}

 

On Exit del Trigger

 

//::///////////////////////////////////////////////
//:: TIERRA DE HEROES - ox_area_efecto
//:: Copyright (c) 2018 Fran Luque (Avernum).
//:://////////////////////////////////////////////
/*
    oe_area_efecto
    oh_area_efecto
    ox_area_efecto
*/
//:://////////////////////////////////////////////
//:: Created By: Fran Luque
//:: Created On: 12/05/2018
//:: Last Updated: 03/04/2020
//:://////////////////////////////////////////////
void main()
{
    object oPC          = GetExitingObject();
    string sFraseExit   = GetLocalString(OBJECT_SELF,"FraseExit");
    int iFXInstant      = GetLocalInt(OBJECT_SELF,   "FXInstantExit");
    string sMiTag       = GetTag(OBJECT_SELF);
    effect eFXInstant;

    if (GetLocalInt(OBJECT_SELF,"AfectaEnemigos")==FALSE)
    {
        if (!GetIsPC(oPC)) return;
    }

    SetLocalInt (oPC, "EfectoAreaEfecto"+sMiTag, FALSE);

    if (sFraseExit!=""){FloatingTextStringOnCreature(sFraseExit, oPC, FALSE);}

    //Quitar efectos aplicados al entrar en trigger - oe_area_efecto
    effect eLoop = GetFirstEffect(oPC);
    while (GetIsEffectValid(eLoop))
    {
        if (GetEffectTag(eLoop)=="EfectoAreaEfecto"+sMiTag)
        {
            RemoveEffect(oPC, eLoop);
        }
        eLoop = GetNextEffect(oPC);
    }

    //FX instantaneo al salir de la zona (VFX_FNF, VFX_IMP, VFX_COM
    if (iFXInstant!=0)
    {
        eFXInstant = EffectVisualEffect(iFXInstant);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eFXInstant, oPC);
    }

} 

 

On Heartbeat del Ubicado controlador (opcional, solo si quieres efectos durante tiempo)

 

//::///////////////////////////////////////////////
//:: TIERRA DE HEROES - oh_area_efecto
//:: Copyright (c) 2020 Fran Luque (Avernum).
//:://////////////////////////////////////////////
/*

    Sistema de Areas de Efecto de Daño

    -Refactorizado: Ahora 1 solo heartbeat por grupo de areas, en vez de N*areas de efecto

    oe_area_efecto
    oh_area_efecto
    ox_area_efecto

    Ejemplo:
    Daño fuego al estar cerca de lava
    Daño de veneno por atmosfera venenosa

    DAMAGE_TYPE_ACID            16
    DAMAGE_TYPE_BLUDGEONING     1
    DAMAGE_TYPE_COLD            32
    DAMAGE_TYPE_DIVINE          64
    DAMAGE_TYPE_ELECTRICAL      128
    DAMAGE_TYPE_FIRE            256
    DAMAGE_TYPE_MAGICAL         8
    DAMAGE_TYPE_NEGATIVE        512
    DAMAGE_TYPE_PIERCING        2
    DAMAGE_TYPE_POSITIVE        1024
    DAMAGE_TYPE_SLASHING        4
    DAMAGE_TYPE_SONIC           2048

    Fuego
        effect eDam = EffectDamage(daño,DAMAGE_TYPE_FIRE);
        effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
    maligno
        effect eDam = EffectDamage(daño,DAMAGE_TYPE_NEGATIVE);
        effect eVis = EffectVisualEffect(VFX_IMP_EVIL_HELP);
    veneno
        effect eDam = EffectDamage(daño,DAMAGE_TYPE_ACID);
        effect eVis = EffectVisualEffect(VFX_IMP_POISON_L);
*/
//:://////////////////////////////////////////////
//:: Created By: Fran Luque
//:: Created On: 12/05/2018
//:: Last Update: 02/05/2020
//:://////////////////////////////////////////////
// Devuelve TRUE o FALSE dependiendo de si hay algun jugador en el area // Uso: if( CheckForPCInArea( GetArea(OBJECT_SELF)  ) == FALSE ){return;}
int CheckForPCInArea(object oArea){object oPC = GetFirstPC();while ( oPC!=OBJECT_INVALID ){if( GetArea(oPC)==oArea ){return TRUE;}else{oPC = GetNextPC();}}return FALSE;}
//:://////////////////////////////////////////////
int CheckForItem(object oQuien, string sTagItem, int iEquipado)
{
    int iLoTienes = FALSE;
    object oItem;
    string sTagoItem;
    int i;
    if (iEquipado==TRUE)
    {
        for (i = 0; i < NUM_INVENTORY_SLOTS; ++i)
        {
            oItem = GetItemInSlot(i, oQuien);
            sTagoItem = GetTag(oItem);
            if (sTagoItem==sTagItem){iLoTienes=TRUE;}
        }
    }
    else if (iEquipado<=0)
    {
        oItem = GetItemPossessedBy(oQuien, sTagItem);
        if (GetIsObjectValid(oItem)){iLoTienes=TRUE;}
    }
    //if (iLoTienes==TRUE){SendMessageToPC(GetFirstPC(), "Tienes el item");}
    return iLoTienes;
}
//:://////////////////////////////////////////////
void AplicarEfectoDMG(object oAreaEfecto, effect eDam, effect eVis, int iEquipado, int iChanceFrase = 0, string sFraseDmg = "", string sItemEscudo = "")
{
    int iVar;
    int iCurrent    =  GetTimeSecond() + 1;
    //object oItemEscudo;
    object oInTrig  =  GetFirstInPersistentObject(oAreaEfecto, OBJECT_TYPE_CREATURE);
    while (oInTrig!=OBJECT_INVALID)
    {
        if (sItemEscudo!=""){ if (CheckForItem(oInTrig, sItemEscudo, iEquipado)==TRUE){return;}}
        iVar = GetLocalInt(oInTrig, "EfectoAreaEfecto"+GetTag(oAreaEfecto));
        //SendMessageToPC(GetFirstPC(), "Nombre oIntrig: "+GetName(oInTrig)+", Tag: ["+GetTag(oInTrig)+"]");
        if ((iVar < 0) || ((iVar > 0) && ((iCurrent + 60 - iVar) > 10)))
        {
            if (-iCurrent != iVar)
            {
                if (d100()<=iChanceFrase && sFraseDmg != ""){ FloatingTextStringOnCreature(sFraseDmg, oInTrig, TRUE); }
                ApplyEffectToObject(DURATION_TYPE_INSTANT,eDam, oInTrig);
                ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis, oInTrig);
            }
        }
        oInTrig = GetNextInPersistentObject(oAreaEfecto, OBJECT_TYPE_CREATURE);
    }
}
//:://////////////////////////////////////////////
void AplicarEfectoFX(object oAreaEfecto, effect eFX)
{
    object oInTrig  =  GetFirstInPersistentObject(oAreaEfecto, OBJECT_TYPE_CREATURE);
    while (oInTrig!=OBJECT_INVALID)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eFX, oInTrig);
        oInTrig = GetNextInPersistentObject(oAreaEfecto, OBJECT_TYPE_CREATURE);
    }
}
//:://////////////////////////////////////////////
void main()
{   //SendMessageToPC(GetFirstPC(), "Oh_Area: "+GetName(GetArea(OBJECT_SELF)));
    if (GetLocalInt(OBJECT_SELF, "ControladorDesactivado")==TRUE){return;}

    object oArea = GetArea(OBJECT_SELF);

    if( CheckForPCInArea( oArea  ) == FALSE ){return;}

    int iTipoDado           =  GetLocalInt(OBJECT_SELF,    "TipoDado");
    int iNumDados           =  GetLocalInt(OBJECT_SELF,    "NumDados");
    int iTipoDmg            =  GetLocalInt(OBJECT_SELF,    "TipoDmg");
    int iFXDMG              =  GetLocalInt(OBJECT_SELF,    "FXDmg");
    int iFXVisual           =  GetLocalInt(OBJECT_SELF,    "FXVisual");
    string sFraseDmg        =  GetLocalString(OBJECT_SELF, "FraseDmg");
    int iChanceFrase        =  GetLocalInt(OBJECT_SELF,    "ChanceFraseDmg");
    string sTagAreaEfecto   =  GetLocalString(OBJECT_SELF, "TagAreaEfecto");
    int iNumAreasEfecto     =  GetLocalInt(OBJECT_SELF,    "NumAreasEfecto");
    string sTagItemEscudo   =  GetLocalString(OBJECT_SELF, "TagItemEscudo");
    int iItemEscudoEquipado =  GetLocalInt(OBJECT_SELF,    "ItemEscudoEquipado");
    effect eFXDMG           =  EffectVisualEffect(iFXDMG);
    effect eFXVisual        =  EffectVisualEffect(iFXVisual);//VFX_DUR_BUBBLES
    effect eDam;
    int iDmg;
    string sTagLoop;
    object oAreaEfecto;

    if (iNumDados <= 0) { iNumDados = 1; }
    if (iTipoDado<=0)   {iTipoDado  = 6; }
    switch (iTipoDado)
    {
        case 2:   iDmg = d2(iNumDados);   break;
        case 3:   iDmg = d3(iNumDados);   break;
        case 4:   iDmg = d4(iNumDados);   break;
        case 6:   iDmg = d6(iNumDados);   break;
        case 8:   iDmg = d8(iNumDados);   break;
        case 10:  iDmg = d10(iNumDados);  break;
        case 12:  iDmg = d12(iNumDados);  break;
        case 20:  iDmg = d20(iNumDados);  break;
        case 100: iDmg = d100(iNumDados); break;
    }

    eDam = EffectDamage(iDmg,iTipoDmg,DAMAGE_POWER_PLUS_TWENTY);

    // -- Loop en Area *viejo y mas costoso en CPU
    /*
    while (oAreaEfecto!=OBJECT_INVALID)
    {
        sTagLoop = GetTag(oAreaEfecto);
        if (sTagLoop==sTagAreaEfecto)
        {
            //Si area activa...
            AplicarEfectoDMG(oAreaEfecto, eDam, eVis, iChanceFrase, sFraseDmg);
        }
        oAreaEfecto = GetNextObjectInArea(oArea);
    }        */
    // -- Fin Loop en Area

    //Optimizacion
    int i;
    for (i=1;i<=iNumAreasEfecto;i++)
    {
        oAreaEfecto = GetNearestObjectByTag(sTagAreaEfecto, OBJECT_SELF, i);
        if (GetIsObjectValid(oAreaEfecto))
        {
            AplicarEfectoDMG(oAreaEfecto, eDam, eFXDMG, iItemEscudoEquipado, iChanceFrase, sFraseDmg, sTagItemEscudo);
            if (iFXVisual!=0){ AplicarEfectoFX(oAreaEfecto, eFXVisual); }
        }
    }


} 

 

Módulo de ejemplo: 

 

https://mega.nz/file...je82_AGGJPmi8P8

 

Clave: 

 

W5VlyavpWFMAH3-Es2MwZmGMpmQMje82_AGGJPmi8P8

 

¡Que lo disfrutéis! 

 

Cualquier idea o mejora es bienvenida.

 

*Para la versión 2, se podrá aplicar más de un efecto por trigger*


Editado por Avernum, 03 May 2020 - 10:25 AM.


#2 Zoraga

Zoraga

    Ancillae

  • Miembro
  • PipPipPip
  • 254 posts

Posteado 03 May 2020 - 09:07 AM

Se ve bastante util, lo estaré probando.

Por cierto, el archivo me pide clave de cifrado.


Editado por Zoraga, 03 May 2020 - 09:08 AM.

Colaborando en:



Nombre servidor: ES) Rebelión del Submundo
Tipo de servidor: rol/acción/jvj
Jugadores: 1-25
Niveles: 1-30
Base literaria: Reinos Olvidados
IP (conectar directamente): sombrasdefaerun.no-ip.org
Foro: http://usn-rol.foroes.org/



 


#3 Avernum

Avernum

    Humano

  • Miembro
  • Pip
  • 14 posts

Posteado 03 May 2020 - 10:26 AM

Enlace actualizado, disculpa.

 

Con el módulo verás rápido algunas cosas que se pueden hacer. 

 

Espero que te sea útil, hay cosas muy chulas.





Responder



  



También marcado con avernum, Tierra de Heroes, scripting

A Bragol. Tus amigos te echan de menos.