# FoxApo DayZ Mods

Welcome to the documentation page, an enchanting oasis dedicated to the exploration and understanding of my DayZ mods.

{% hint style="info" %}
**Tip:** If you find any kind of information missing, do not hesitate to contact me on the Discord and raise a suggestion to update fill up the missing gap.&#x20;
{% endhint %}

## Get Started

I've put together some pages about the mods I have been working on and also provide you a deep understanding how my mods work.&#x20;


# Modding | Repacking

In DayZ, people often misunderstand the point of modding and I have come across many situations where people tend to repack the mods instead of simple modding or making an overrides.&#x20;

The point of modding is to modify the current functionality in the game or a mod from the workshop.&#x20;

Repacking is when you take the mod and pack it to your other mod which can be beneficial but also it has many cons people are not aware of.&#x20;

I would like to help you understand better the point of making overrides and modding in general and reason why it's a good practice to write your own override before trying to repack.&#x20;

Not only you keep the original mod functional and referenced to its original author, but you are also keeping the original mod updated so you don't have to care about potential update on the workshop and repacking it again and again. And most importantly, you safe the space.&#x20;

People often say, that repacks safe the performance. This can be true in many cases because you're loading just a packed pbo into the memory and don't have to load multiple at once but in the final state, it's almost the same as if you would load up the multiple mods because you are loading the same scripts as it would be split into several pbo, apart from the headers and some crucial meta files from the mod itself. It's a very speculative topic and it is understandable that people want to have less mods visible in the server browser and more consistent setup in terms of their mod structure and stuff.&#x20;

But most of the server owners and people who are just using the mods are not aware of simple fact, that you're basically reusing the same data as there are already uploaded on the workshop and downloaded by other clients.&#x20;

Let's say you are repacking a huge mod with models and textures which has gigabites of data. When you repack this mod, you're making a copy of the mod on the workshop with different id and basically consume another same amount of space on the steam servers, which doesn't have to be your business as you think. But let's imagine that there would be repack for the whole SNAFU mod on each server you want to play.&#x20;

Whenever you would try to play on a different server, you would need to download the same amount of data again and again just because the server has it's own repacked version.&#x20;

You would have 20 favorite servers you are playing and you would need to download 20x\~3GB of mod just to be able to play on those servers. That's already a 60GB of data because people are lazy and think that repacks brings benefits for them. Not only they hide & lie that they are using the SNAFU mod, they will just consume additional space on the peoples machines and more space on the cloud storage. In general it's a big dummy move and that's the reason I would like to explain how to make overrides and do the modding in a more reasonable way.&#x20;


# CRDTN Creatures

Pack of scripted creatures for DayZ


# Phantom

Phantom is a custom script inspired by stalker's phantom dogs which are able to clone and emit psi energy.

This mod requires [CRDTN Core](/mods/crdtn-core) as depandancy so if you don't have the Core, please refer to that and install it from the workshop.&#x20;

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2Fto37XK2o5ybjsIWxDV1S%2Fimage.png?alt=media&amp;token=a20f6d11-4c65-4f29-a3f8-239eed8dfd87" alt=""><figcaption><p>Dude standing on the railroad</p></figcaption></figure>

## Installation

Download the mod from workshop.&#x20;

## How to use

#### **Client side**&#x20;

You can use the built in phantom classes which are based on the vanilla wolfs.&#x20;

* <pre><code><strong>CRDTN_PhantomWolfGrey
  </strong></code></pre>

  <pre><code><strong>CRDTN_PhantomWolfWhite
  </strong></code></pre>

Or you can make your own :)&#x20;

* Create an empty mod or use your server mod, or any other mod of your own. Do not modify the mod from the workshop. *It is prohibited to repack this mod and modify it unless you have the permission.*&#x20;

You can use the full potential without any need to modify the original mod.&#x20;

You must inherit your animal class from the `CRDTN_Creature_PhantomBase`&#x20;

The phantom class expects parameters being set in the config.cpp. No json or any other config file needed.&#x20;

#### Example with AoD assets&#x20;

Use the following example to get the idea, how to properly attach your animals to the script and do make it phantom.&#x20;

````csharp
```
class CfgVehicles {

    class AnimalBase;
    class Animal_CanisLupus : AnimalBase {};
    
    class Mutant_AoD_Pse_Dog_Base : Animal_CanisLupus 
    {
        scope = 0;
        phantomType = "Mutant_AoD_Pse_Dog2";     // Set on the subclasses
        phantomCount = 5;                        // Max phantom count
        phantomSpawnTimer = 3;                   // Interval of spawning in seconds
        phantomCheckTimer = 1;                   // Interval of checking in seconds
        phantomRadius = 10;                      // Spawn Radius
        phantomEffectDistance = 30;              // Meters
        phantomSize = 0.2;                       // Not working at the moment
    };
    
    class Mutant_AoD_Pse_Dog1 : Mutant_AoD_Pse_Dog_Base 
    {
        scope = 2;
        phantomType = "Mutant_AoD_Pse_Dog2"; // Set on the subclasses
    };
    
    class Mutant_AoD_Pse_Dog2 : Mutant_AoD_Pse_Dog_Base {};
    
};
```
````

Create a script in module *4\_World*

*You can literally place it wherever you need, just make sure, this script is loaded on the client side.*&#x20;

````cpp
```
class Mutant_AoD_Pse_Dog_Base : CRDTN_Creature_PhantomBase {};
class Mutant_AoD_Pse_Dog1 : Mutant_AoD_Pse_Dog_Base {};
class Mutant_AoD_Pse_Dog2 : CRDTN_Creature_Minion {};
```
````

#### Server side

Server side mod is part of the workshop item. To install the server side mod, you just need to place the pbo in the Addons folder of your server. If you use Omega and similar tools, make sure the mod is properly loaded on the server.&#x20;


# config.cpp

```csharp
class CfgPatches
{
    class CRDTN_Client_Creatures
    {
        units[]          = { "CRDTN_PhantomWolfGrey", "CRDTN_PhantomWolfWhite" };
        weapons[]        = {};
        requiredVersion  = 0.1;
        requiredAddons[] = { "DZ_Data", "DZ_Scripts", "DZ_Animals", "CRDTN_Core" };
        defines[]        = {"CRDTN_Creatures"};
    };
};

class CfgMods
{

    class CRDTN_Client_Creatures
    {
        name           = "FOX Coradiation ClientMod for the Creatures";
        credits        = "Big Kudos to guys from the Renegade Stalker Server for providing valuable information";
        author         = "FoxApoGames - Freeman";
        type           = "mod";
        dependencies[] = {"Game", "World"};
        dir            = "CRDTN_Client_Creatures";

        class defs
        {
            class gameScriptModule
            {
                value   = "";
                files[] = {"CRDTN_Client_Creatures/Scripts/3_Game"};
            };
            class worldScriptModule
            {
                value   = "";
                files[] = {"CRDTN_Client_Creatures/Scripts/4_World"};
            };
        };
    };
};

class CfgVehicles
{
    class HouseNoDestruct;

    class CRDTN_FX_Phantom_Spawn: HouseNoDestruct
    {
        scope  = 2;
        weight = 99999999;
    };
    class CRDTN_FX_Phantom_Despawn: HouseNoDestruct
    {
        scope  = 2;
        weight = 99999999;
    };

    class AnimalBase;
    class Animal_CanisLupus: AnimalBase
    {
    };
    class CRDTN_CreaturePhantomWolfBase: Animal_CanisLupus
    {
        simulation          = "dayzanimal";
        scope               = 0;
        model               = "\DZ\animals\canis_lupus\canis_lupus.p3d";
        displayName         = "Phantom Dog";
        descriptionShort    = "$STR_CfgVehicles_Animal_CanisLupus1";
        hiddenSelections[]  = {"Camo", "CamoHair"};
        DamageSphereAmmos[] = {"MeleeWolf"};
        aiAgentTemplate     = "Predators_Wolf";
        injuryLevels[]      = {1.0, 0.5, 0.2, 0.0};
                                                            // Phantom Variables
        phantomType           = "Animal_CanisLupus_White";  // Set on the subclasses
        phantomCount          = 5;                          // Max phantom count
        phantomSpawnTimer     = 3;                          // Interval of spawning in seconds
        phantomCheckTimer     = 1;                          // Interval of checking in seconds
        phantomRadius         = 10;                         // Spawn Radius
        phantomEffectDistance = 30;                         // Meters
        phantomSize = 0.2;

        class DamageSystem
        {
            class GlobalHealth
            {
                class Health
                {
                        // 600 HP - can be increased
                    hitpoints      = 1200;
                    healthLevels[] = {{1.0, {}}, {0.7, {}}, {0.5, {}}, {0.3, {}}, {0.0, {}}};
                };
                class Blood
                {
                    hitpoints = 5000;
                };
                class Shock
                {
                    hitpoints = 100;
                };
            };
            class DamageZones
            {
                class Zone_Head
                {
                    componentNames[]       = {"Zone_Head"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.15;
                    canBleed               = 0;
                    class Health
                    {
                        hitpoints            = 120;
                        transferToGlobalCoef = 1;
                    };
                    class Blood: Health
                    {
                        hitpoints = 0;
                    };
                    class Shock: Health
                    {
                        hitpoints = 0;
                    };
                };
                class Zone_Neck: Zone_Head
                {
                    componentNames[]       = {"Zone_Neck"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.05;
                    class Health: Health
                    {
                        hitpoints = 100;
                    };
                };
                class Zone_Chest: Zone_Head
                {
                    componentNames[]       = {"Zone_Chest"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.05;
                    class Health: Health
                    {
                        hitpoints = 150;
                    };
                };
                class Zone_Belly: Zone_Head
                {
                    componentNames[]       = {"Zone_Belly"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.05;
                    class Health: Health
                    {
                        hitpoints = 150;
                    };
                };
                class Zone_Spine: Zone_Head
                {
                    componentNames[]       = {"Zone_Spine_Front", "Zone_Spine_Back"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.05;
                    class Health: Health
                    {
                        hitpoints = 150;
                    };
                };
                class Zone_Pelvis: Zone_Head
                {
                    componentNames[]       = {"Zone_Pelvis"};
                    transferToZonesNames[] = {"Zone_Spine"};
                    transferToZonesCoefs[] = {0.5};
                    fatalInjuryCoef        = 0.05;
                    class Health: Health
                    {
                        hitpoints = 180;
                    };
                };
                class Zone_Legs: Zone_Head
                {
                    componentNames[]       = {"Zone_Legs_Front", "Zone_Legs_Back"};
                    transferToZonesNames[] = {};
                    transferToZonesCoefs[] = {};
                    fatalInjuryCoef        = 0.0;
                    class Health: Health
                    {
                        hitpoints = 100;
                    };
                };
            };
        };
        class Skinning
        {
            class ObtainedSteaks
            {
                item                 = "WolfSteakMeat";
                count                = 10;
                itemZones[]          = {"Zone_Chest", "Zone_Belly", "Zone_Pelvis"};
                countByZone[]        = {3.0, 3.0, 3.0};
                quantityMinMaxCoef[] = {0.5, 1};
            };
            class ObtainedPelt
            {
                item                   = "WolfPelt";
                count                  = 1;
                itemZones[]            = {"Zone_Chest", "Zone_Belly"};
                quantityCoef           = 1;
                transferToolDamageCoef = 1;
            };
            class ObtainedGuts
            {
                item                 = "Guts";
                count                = 2;
                quantityMinMaxCoef[] = {0.5, 0.8};
            };
            class ObtainedLard
            {
                item                 = "Lard";
                count                = 1;
                quantityMinMaxCoef[] = {0.5, 1};
            };
            class ObtainedBones
            {
                item                   = "Bone";
                count                  = 1;
                quantityMinMaxCoef[]   = {0.7, 1};
                transferToolDamageCoef = 1;
            };
        };
        class enfanimsys
        {
            meshObject      = "dz\animals\canis_lupus\Data\canis_lupus_skeleton.xob";
            graphname       = "dz\animals\animations\!graph_files\Wolf\Wolf_Graph.agr";
            defaultinstance = "dz\animals\animations\!graph_files\Wolf\Wolf_AnimInstance.asi";
            startnode       = "AlignToTerrain_Rot";
            skeletonName    = "canis_lupus_skeleton.xob";
        };
        class AnimEvents
        {
            class Steps
            {
                class Walk1
                {
                    soundLookupTable = "PawMediumWalk_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 1;
                };
                class Walk2
                {
                    soundLookupTable = "PawMediumWalk_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 2;
                };
                class Walk3
                {
                    soundLookupTable = "PawMediumWalk_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 3;
                };
                class Walk4
                {
                    soundLookupTable = "PawMediumWalk_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 4;
                };
                class Run1
                {
                    soundLookupTable = "PawMediumRun_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 5;
                };
                class Run2
                {
                    soundLookupTable = "PawMediumRun_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 6;
                };
                class Run3
                {
                    soundLookupTable = "PawMediumRun_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 7;
                };
                class Run4
                {
                    soundLookupTable = "PawMediumRun_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 8;
                };
                class Bodyfall
                {
                    soundLookupTable = "PawMediumBodyfall_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 11;
                };
                class Settle
                {
                    soundLookupTable = "PawMediumSettle_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 12;
                };
                class Rest2standA
                {
                    soundLookupTable = "PawMediumRest2standA_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 13;
                };
                class Rest2standB
                {
                    soundLookupTable = "PawMediumRest2standB_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 14;
                };
                class Stand2restA
                {
                    soundLookupTable = "PawMediumStand2restA_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 15;
                };
                class Stand2restB
                {
                    soundLookupTable = "PawMediumStand2restB_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 16;
                };
                class Stand2restC
                {
                    soundLookupTable = "PawMediumStand2restC_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 17;
                };
                class Jump
                {
                    soundLookupTable = "PawMediumJump_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 18;
                };
                class Impact
                {
                    soundLookupTable = "PawMediumImpact_LookupTable";
                    noise            = "WolfStepNoise";
                    effectSet[]      = {"WolfStepEffect1", "WolfStepEffect2"};
                    id               = 19;
                };
            };
            class Sounds
            {
                class WolfBark
                {
                    soundSet = "WolfBark_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 1;
                };
                class WolfBark_1
                {
                    soundSet = "WolfBark_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 61;
                };
                class WolfBark_2
                {
                    soundSet = "WolfBark_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 71;
                };
                class WolfBark2
                {
                    soundSet = "WolfBark2_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 2;
                };
                class WolfBark3
                {
                    soundSet = "WolfBark3_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 3;
                };
                class WolfBreath
                {
                    soundSet = "WolfBreath_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 4;
                };
                class WolfGroans
                {
                    soundSet = "WolfGroans_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 5;
                };
                class WolfGrowl_A
                {
                    soundSet = "WolfGrowl_A_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 6;
                };
                class WolfGrowl_B
                {
                    soundSet = "WolfGrowl_B_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 7;
                };
                class WolfGrowl
                {
                    soundSet = "WolfGrowl_A_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 8;
                };
                class WolfPant
                {
                    soundSet = "WolfPant_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 9;
                };
                class WolfPantShort
                {
                    soundSet = "WolfPantShort_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 10;
                };
                class WolfPantLong
                {
                    soundSet = "WolfPantShort_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 18;
                };
                class WolfSnarl
                {
                    soundSet = "WolfSnarl_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 11;
                };
                class WolfSnarlShort
                {
                    soundSet = "WolfSnarlShort_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 12;
                };
                class WolfWhimper
                {
                    soundSet = "WolfWhimper_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 13;
                };
                class WolfYelp
                {
                    soundSet = "WolfYelp_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 14;
                };
                class WolfYawn
                {
                    soundSet = "WolfYelp_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 15;
                };
                class WolfDeath
                {
                    soundSet = "WolfDeath_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 20;
                };
                class WolfHowl
                {
                    soundSet = "WolfHowl_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 16;
                };
                class WolfHowls
                {
                    soundSet = "WolfHowls_SoundSet";
                    noise    = "WolfRoarNoise";
                    id       = 17;
                };
            };
            class Damages
            {
                class Bite
                {
                    damage = "WolfBiteDamage";
                    id     = 1;
                };
                class BiteLow
                {
                    damage = "WolfLowBiteDamage";
                    id     = 2;
                };
            };
        };
        class CommandMoveSettings
        {
            useSpeedMapping        = 1;
            movementSpeedMapping[] = {0.0, 0.25, 0.5, 1.2, 4.5, 12.2};
        };
        class CommandLookAtSettings
        {
            lookAtFilterTimeout = 0.5;
            lookAtFilterSpeed   = 1.57;
        };
    };

    class CRDTN_PhantomWolfGrey: CRDTN_CreaturePhantomWolfBase
    {
        scope                      = 2;
        phantomType                = "CRDTN_Creature_Minion_Grey";
        hiddenSelectionsTextures[] = {
            "dz\animals\canis_lupus\data\wolf_grey_CO.paa",
            "dz\animals\canis_lupus\data\fur_alpha.paa"};
    };
    class CRDTN_PhantomWolfWhite: CRDTN_CreaturePhantomWolfBase
    {
        scope                      = 2;
        phantomType                = "CRDTN_Creature_Minion_White";
        phantomCount               = 10;
        phantomSpawnTimer          = 2;
        phantomSize                = 0.2;
        hiddenSelectionsTextures[] = {
            "dz\animals\canis_lupus\data\wolf_grey_CO.paa",
            "dz\animals\canis_lupus\data\fur_alpha.paa"};
    };

    class CRDTN_Creature_Minion: Animal_CanisLupus
    {
        scope            = 0;
        displayName      = "Psuedo Dog (Minion)";
        descriptionShort = "A dog that is not a dog.";
    };

    class CRDTN_Creature_Minion_Grey: CRDTN_Creature_Minion
    {
        scope                      = 2;
        hiddenSelectionsTextures[] = {
            "dz\animals\canis_lupus\data\wolf_grey_CO.paa",
            "dz\animals\canis_lupus\data\fur_alpha.paa"};
    };

    class CRDTN_Creature_Minion_White: CRDTN_Creature_Minion
    {
        scope                      = 2;
        hiddenSelectionsTextures[] = {
            "dz\animals\canis_lupus\data\wolf_white_CO.paa",
            "dz\animals\canis_lupus\data\fur_alpha.paa"};
    };
};
```


# CRDTN Core

A client/server side mod which is a foundation for my other mods. It's a simple package with various functions that can be used across multiple mods and server owners can benefit from those in their custom mods. Server side mod is not required. You can also use this mod as allows server owners extend their game experience by adding my notification UI and custom sounds.

For those who are not very familiar with scripting, I would suggest to take a look on the documentation or join my discord and ask for help. It's a nice simple mod which can help you to get things sorted out and maybe understand better how to structure a simple mod.

This mod is important for the other CRDTN mods to get things organized and consistent so please be aware that repacking of this mod does not bring you any benefit. Rather visit a public github repository with a source code and do some study or read the docs.

### Features in nutshell:

* Notifications
* Sound upon login to game
* Event handler
* Generic UI List Entry and UI Menu
* \[In Progress] Preparation of Post Processing requester
* \[In Progress] Preparation of Camera utility class for easier manipulation with camera

#### Config $profiles/CRDTN/CRDTN\_Core.json

```json
{
    "CRDTN_ServerName": "CRDTN Test Server",
    "CRDTN_IntroSoundSet": "CRDTN_Core_SoundSet_Music_Tension1",
    "CRDTN_Notifications":  "CRDTN_Core/Layouts/Notifications/notification_element.layout",
    "CRDTN_NotificationsWrapper" : "CRDTN_Core/Layouts/Notifications/notifications.layout",
    "CRDTN_DisableIntroNotification" : false,
    "CRDTN_UseVanillaNotifications" : false,
    "CRDTN_Debug": true,
    "CRDTN_IntroMusic": true
}
```

* If you don't like the notification look & feel, you can always use the **vanilla notifications** by putting the following value in the config to **CRDTN\_Notifications** parameter

```json
"CRDTN_UseVanillaNotifications" : true
```

#### Usable sound sets

You can use various Sound Sets from the mod which are licenced or aquired songs with permission from their respective authors. Please bare in mind that commercial usage of these sound effects is strictly prohibited so before you want to use this song in your mod, please raise a support ticket on my discord and we can allow you to use it. There is no need to steal this thing and do it without a permission. Some songs are used from the bought asset packs for Unity and some are acquired with the permission from Good Malware or Magnality. Both authors are members of my discord channel so if you want to contact them, do not hesitate to join the discord and write them a message.

```
CRDTN_Core_SoundSet_Music_Zone
CRDTN_Core_SoundSet_Music_InvisibleThreat
CRDTN_Core_SoundSet_Music_Oxido
CRDTN_Core_SoundSet_Music_Tension1
CRDTN_Core_SoundSet_Music_Tension2
CRDTN_Core_SoundSet_Music_OldOne
```

#### Usable font

If you like the fond of CRDTN mods, you can search for **Rajdhani** or use following variants of font:

```
// Light
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light16
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light20
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light22
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light24
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light26
CRDTN_Core/data/fonts/Rajdhani-Light/Rajdhani-Light28
// Medium
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium12
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium14
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium16
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium22
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium28
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium48
CRDTN_Core/data/fonts/Rajdhani-Medium/Rajdhani-Medium58
// Bold
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold12
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold14
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold16
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold22
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold28
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold48
CRDTN_Core/data/fonts/Rajdhani-Bold/Rajdhani-Bold58
```

Thank you for checking out my Mod. Creating and maintaining mods takes time and effort, but I enjoy every moment of it. If you've found my Mod useful, entertaining, or it has enhanced your gaming experience in any way, and you feel inclined to support my work, I would sincerely appreciate any contribution you can make.

Donations are completely optional and not expected, but they do go a long way in helping me continue developing and improving this Mod. Your generosity enables me to invest more time and resources into creating new features, fixing bugs, and providing ongoing support to the community.


# File Logger

With the latest update I have added a custom file logger, which you can create in your code and save the logging results to your custom folder.

Let's create a logger with name **TestLogger**

This modded script should be created in *Module #3 - 3\_Game,* so you can access that across the whole app. Otherwise you can choose a different place. I just think it's convenient to have it accessible from most of the codebase of DayZ Server.&#x20;

```csharp
// Create a modded class for DayZGame script
modded class DayZGame
{
    override void CRDTN_OnGameInit()
    {
        super.CRDTN_OnGameInit();
        CRDTN_FileLogger.CreateInstance("TestLogger");
        // instantiates the instance of FileLogger with key - TestLogger
        // 
    }
};
```

Congratulations, you have create your logger :joy: The file will be saved in ***$profile/CRDTN/Logs/TestLogger.log***

If you want a different location for your logs, you must rewrite the constant&#x20;

```c
CFG_CRDTN_LogsFolder
```

Now you can access it from your code wherever you need by using the following code snippet.

```c
CRDTN_FileLogger.GetInstance("TestLogger").Log("Some of your message");
```

You can also cache the reference for more convenient work like below.&#x20;

```csharp
class TestPlugin : CRDTN_PluginBase
{
    private ref CRDTN_FileLogger m_TestLogger;
    
    override void OnInit()
    {
        super.OnInit();
        m_TestLogger = CRDTN_FileLogger.GetInstance("TestLogger");
    }
    
    CRDTN_FileLogger GetTestLogger()
    {
        return m_TestLogger;
    }
};

TestPlugin GetTestPlugin()
{
    if (!GetGame().IsServer())
    {
        return NULL;
    }

    if (GetPluginManager() && GetPluginManager().GetPluginByType(TestPlugin))
    {
        return TestPlugin.Cast(GetPluginManager().GetPluginByType(TestPlugin));
    }

    return NULL;
}

CRDTN_TestLogger GetLogger()
{
    return GetTestPlugin().GetTestLogger();
}
```

If you have followed the code above, you now can just call in the code&#x20;

```csharp
GetLogger().Log("Some message");
```

Be aware, that the example showcases usage of **PluginBase** which is part of module #4 so you can use the **GetLogger()** method only within module #4 and #5.&#x20;


# Logger Player Connected

In this example, I will show you how to create a logger for player connection so basically a file, which contains an information of time and connected player.

Create a Game.c in Module 3


# Rest Api

CRDTN Core supports using of Rest Api in a more convenient way. Sometimes you want to get some data from the internet during runtime of your server. You can use this for various things.

### Example of usages

There can be multiple reasons why to use Rest Api. Unfortunately the DayZ support of the rest api is quite limited so you might need to cope with just a couple methods comparing to regular approach of the usage of rest api for instance on the Web Applications you daily use.&#x20;

Rest Api allows you to call requests on the external network endpoints to receive a response of your desired state.&#x20;

For example, you can store some data on the external database and access those only through the rest api from your server so you are not caching and storing these data directly on the server memory.&#x20;

Common usecase might be a usage of an external database for shop database or some player statistics data, which you might also expose on the website of your server or discord.&#x20;

Another example might be some kind of authentication against backend server to protect your mod from using on somewhere else. This can be unfortunately always reverse engineered and until we do not have any reasonable way how to lock our mod files, this can be always bypassed if someone skilled would find a way to override these lines of codes.&#x20;

### My example of usage

I came to this approach in DayZ mods because I hate how people are not willing to accept hard work behind the mod creation and toxicity of some individuals is above the sky so because of this I decided to go a bit different way and rip off some key logic of my mods to an external server where noone else has access. This makes the mod basically unusable without the rest api. It's the only way I found to be reasonable for me and other users who are willing to accept this fact, that if you use my mod, your server will send a small piece of data to my server. On the other hand, by using my mods and this method, you're going with me against those ass holes who steal the mods and do bad stuff with them.&#x20;

###


# Getting started

Let's dive into that and create a new empty class. It depends where you would like to use this class so choose the respective module based on your case. I chose module **4\_World**

<pre class="language-csharp" data-overflow="wrap" data-line-numbers><code class="lang-csharp">class ExampleApi
{
    // Suggestion is to cache the api reference (do not create new instance for each call) 
<strong>    protected ref CRDTN_RestApiWrapper m_RestApi;
</strong>};
</code></pre>

As you can see, I just made an empty class with a cached reference to a RestApi wrapper class instance. Let's add the constructor to the class and setup the API upon the constructing our class **ExampleApi**

<pre class="language-csharp" data-overflow="wrap" data-line-numbers><code class="lang-csharp">class ExampleApi
{
    // Suggestion is to cache the api reference (do not create new instance for each call) 
<strong>    protected ref CRDTN_RestApiWrapper m_RestApi;
</strong><strong>    
</strong><strong>    void ExampleApi()
</strong><strong>    {
</strong><strong>        // https://my-backend-server
</strong><strong>        string url = ""; // Use some endpoint you need to call request on 
</strong><strong>        m_RestApi = new CRDTN_RestApiWrapper(url);
</strong><strong>    }
</strong>};
</code></pre>

#### Using GET method

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```csharp
// Instantiate the api instance for the URL 
autoptr CRDTN_RestApiWrapper m_RestApi = new CRDTN_RestApiWrapper("https://my-backend-server");

// Using callback events
m_RestApi.ExecuteRequest("/endpoint", "GET", "");
```

{% endcode %}

#### Using POST method

{% code fullWidth="false" %}

```csharp
RestApiResponse<string> requestData = new RestApiResponse<string>();
requestData.requestType = typename.EnumToString(RestApiRequestType, RestApiRequestType.AUTH_TEST);
requestData.uniqueId = "testUser";
string data = JsonFileLoader<RestApiResponse<string>>.JsonMakeData(requestData);
m_RestApi.ExecuteRequest("/api/auth", "POST", data);
```

{% endcode %}


# Event Handler


# Notifications UI


# Admin Utils

Admin utils is just a simple container for cache of player ids, which are elligible as admins.

Setup your CRDTN\_Config.json

```json
// Add this parameter to the core config
"CRDTN_AdminList": [
    "avCdzuTN2GEbHlqfPk2wXFvUyxW7CVe50bFIWgDCvN0="
]
```


# NPCs

You can spawn following npcs. Each npc has it's own display name, it's immortal and can be equipped with stuff.

### TYPES

```

CRDTN_SurvivorM_Mirek
CRDTN_SurvivorM_Boris
CRDTN_SurvivorM_Cyril
CRDTN_SurvivorM_Denis
CRDTN_SurvivorM_Elias
CRDTN_SurvivorM_Francis
CRDTN_SurvivorM_Guo
CRDTN_SurvivorM_Hassan
CRDTN_SurvivorM_Indar
CRDTN_SurvivorM_Jose
CRDTN_SurvivorM_Kaito
CRDTN_SurvivorM_Lewis
CRDTN_SurvivorM_Manua
CRDTN_SurvivorM_Niki
CRDTN_SurvivorM_Oliver
CRDTN_SurvivorM_Peter
CRDTN_SurvivorM_Quinn
CRDTN_SurvivorM_Rolf
CRDTN_SurvivorM_Seth
CRDTN_SurvivorM_Taiki
CRDTN_SurvivorF_Eva
CRDTN_SurvivorF_Frida
CRDTN_SurvivorF_Gabi
CRDTN_SurvivorF_Helga
CRDTN_SurvivorF_Irena
CRDTN_SurvivorF_Judy
CRDTN_SurvivorF_Keiko
CRDTN_SurvivorF_Linda
CRDTN_SurvivorF_Maria
CRDTN_SurvivorF_Naomi
CRDTN_SurvivorF_Baty

```

### SPAWNING

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```c
EntityAI npc = EntityAI.Cast(GetGame().CreateObject("CRDTN_SurvivorF_Linda", "0 0 0", false, true));
autoptr TStringArray equipment = {"MilitaryBoots_Bluerock","WoolGloves_Green","Spur_CamelBag_Green","NBCPantsGray"};
if (equipment.Count() > 0)
{
    for (int i = 0; i < equipment.Count(); i++)
    {
        ent.GetInventory().CreateAttachment(equipment.Get(i));
    }
}
// Equip the weapon
CRDTN_NPCSurvivorBase crdtn_survivor = CRDTN_NPCSurvivorBase.Cast(ent);
if(!crdtn_survivor)
{
   return;
}

if(fromTypeOnly)
{
    crdtn_survivor.EquipInHands("WEAPON CLASSNAME");
}
```

{% endcode %}


# CRDTN Gui

Client side mod which overhauls the vanilla UI with a custom font and colors with some minor custom elements.

![](https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2F9QqXnAQcyYyZQbkhTVYH%2Fimage.png?alt=media\&token=481e79ce-2ebe-469e-b724-e40c2a6840c5)![](https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FMyPiMJnVkmiuMW5gi3j1%2Fimage.png?alt=media\&token=e24e66b6-393b-4fcb-8c8c-21b160862fa5)

![](https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FiGrtiqvG8tBRA8EGrcV5%2Fimage.png?alt=media\&token=633cb649-248e-43fd-8bc1-338932084ee4)

The mod is still under development and be aware that it overrides and changes varioius UI elements. It can be conflicting with other UI mods and cause issues if you are not sure which mod does what. Take this in consideration please.&#x20;

## Steam link

<https://steamcommunity.com/sharedfiles/filedetails/?id=3017923865>


# CRDTN Krabice

Complete stash system solution


# CRDTN Factions

under development

This mod is under development.&#x20;


# CRDTN Quests

CRDTN Quests is a mod tinkered for DayZ server owners who are keen to add a new PVE experience into their worlds. This complex system allows players to use their own quest log and complete tasks.

This system allows various types of quests with various types of sub-goals.&#x20;


# Getting started

During the time I have received many questions and some problematic came out with the quest mod. Fortunately I can answer these questions and let you know, how to properly setup this system.

General point of this mod is to add a new game mechanic in the game and let the players complete various tasks and receive some kind of rewards for them. It's a common game mechanic in many games and DayZ is missing this amazing feature.&#x20;


# Client Side

This is a high level overview of how the Client side mod is structured. If you are not familiar with some of the points, please give me a comment on Discord or here and I will do my best to help.

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FBiepeP8arzN5kWmUJRYf%2Fimage.png?alt=media&amp;token=f0fafb84-5a9f-45fc-9885-d951615ba8ff" alt=""><figcaption><p>Quest Log</p></figcaption></figure>

1. Currently ready to complete quest&#x20;
   * Ready quest to complete is green
   * Quest required by the current giver is surrounded by square brackets `[]`
2. Available quests to take at the current giver
   * Quests that are currently available to take are white and in the active quests section
3. Currently active quests&#x20;
   * Quests that are active at player
   * If the quest is surrounded by square brackets, but it's yellow, it means that you are at the quest giver who you can complete the quest, once you complete that.&#x20;
4. Goals of the currently selected quest&#x20;

<details>

<summary>Game Module (3_Game)</summary>

* Constants&#x20;
  * Base configuration of the mod&#x20;
* Debug class&#x20;
  * Helper class to handle the output of the scripts running on the server
* Icon Resolver&#x20;
  * Helper class to validate icons based on the certain conditions&#x20;

</details>

<details>

<summary>World Module (4_World)</summary>

* Classes
* Entities
  * Entity related scripts which overrides the main game logic on entities&#x20;
    * House
    * PlayerBase
    * ItemBase&#x20;
* GUI
  * UI related class for the widgets and client interaction
* Plugins
  * Client side quest plugin to communicate with the server through RPC&#x20;
* Static
  * Utility classes for generic functionality&#x20;

</details>

<details>

<summary>Mission Module (5_Mission)</summary>

* Mission Gameplay

</details>


# Server Side


# Installation

Server config is loaded from the **profiles** folder of **CRDTN** on your server instance.&#x20;

1. Create a *CRDTN* in **$profiles/CRDTN**&#x20;
2. **Create&#x20;*****CRDNT\_Core.json***

````json
```json
{
    "CRDTN_ServerName"              : ">> EXAMPLE NAME <<",
    "CRDTN_IntroSoundSet"           : "CRDTN_Core_SoundSet_Music_Oxido",
    "CRDTN_NotificationsWrapper"    : "CRDTN_Core/Layouts/Notifications/notifications.layout",
    "CRDTN_Notifications"           : "CRDTN_Core/Layouts/Notifications/notification_element.layout",
    "CRDTN_UseVanillaNotifications" : 0,
    "CRDTN_DisableIntroNotification": 0,
    "CRDTN_Debug"                   : 1,
    "CRDTN_IntroMusic"              : 0,
    "CRDTN_AdminList"               : [ "avCdzuTN2GEbHlqfPk2wXFvUyxW7CVe50bFIWgDCvN0=" ],
    "CRDTN_Packages": {}
}
```
````

3. Create *Quests* folder in *CRDTN* folder

* If you want to enable logging, you can create a *Logs* folder

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FtWvxMlpEwAL1MI9Lfm7c%2Fimage.png?alt=media&amp;token=0074632a-3221-44e6-8e20-8605f5ee014d" alt=""><figcaption><p>CRDTN folder in $profiles/CRDTN</p></figcaption></figure>

4. Create the files and folders so it looks like the following image

   <mark style="color:red;">**CAREFULLY -**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`AdditinalQuests`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**= there is a typo!!!!**</mark>

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FlAGGJu4glJKW2WAbYd93%2Fimage.png?alt=media&amp;token=ecaa428b-d477-450a-ab1f-e0579188059f" alt=""><figcaption><p>Quests folder in $profiles/CRDTN/Quests</p></figcaption></figure>

````json
```json
{
    "QuestLogTheme": "",
    "ResetQuestsAfterDeath": 1,
    "Version": 3,
    "QuestKey": "",
    "AdditionalQuests": [
        "intro.json"
    ],
    "QuestSoundSetAbandon": "CRDTN_SoundSet_StalkerSounds_Pda_Alarm",
    "QuestSoundSetComplete": "CRDTN_SoundSet_StalkerSounds_Pda_Tip",
    "QuestSoundSetAccept": "CRDTN_SoundSet_StalkerSounds_Pda_Objective",
    "QuestSoundSetToggle": "CRDTN_SoundSet_StalkerSounds_Pda_Btn_Press"
}
```
````

{% code fullWidth="true" %}

```markup
QuestLogTheme             - Stalker or empty 
ResetQuestsAfterDeath     - Resets all the quest progress when a player dies
Version                   - Not important
QuestKey                  - Not important
AdditionalQuests          - Array of filenames which are supposed to be loaded on top
                            of the Quests.json file 
                            These files additional need to be place in the AdditinalQuests


```

{% endcode %}

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FoF2sjghnvgl0RmdswWVo%2Fimage.png?alt=media&amp;token=b100389c-964e-4a6f-ae6b-fbe2c3a40fdd" alt=""><figcaption><p>AdditionalQuests in $profiles/CRDTN/AdditionalQuests</p></figcaption></figure>

<mark style="color:blue;">Make sure you're using</mark> [<mark style="color:blue;">@CRDTN Core</mark>](/mods/crdtn-core) <mark style="color:blue;">mod and the main</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**Quests.json**</mark> <mark style="color:blue;"></mark><mark style="color:blue;">file is in the Quests folder of</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**CRDTN**</mark><mark style="color:blue;">. This json file is a foundational quest file and you can leave it empty or setup some quests in that. It's there due to a backwards compatibility, but since the update</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**0.6**</mark><mark style="color:blue;">, you are able to use</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**AdditionalQuests**</mark> <mark style="color:blue;"></mark><mark style="color:blue;">parameter in the</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**Settings.json**</mark> <mark style="color:blue;"></mark><mark style="color:blue;">and setup multiple files.</mark>&#x20;

**$profiles/CRDTN/Settings.json**

````json
```jsonc
{
    "QuestLogTheme": "default",
    "ResetQuestsAfterDeath": 1,
    "Version": 3,
    "QuestKey": "",
    "AdditionalQuests": [
        "FILE_1.json",
        "FILE_2.json"
    ],
    "QuestSoundSetAbandon": "CRDTN_Quests_SoundSet_Cancel",
    "QuestSoundSetComplete": "CRDTN_Quests_SoundSet_Short",
    "QuestSoundSetAccept": "CRDTN_Quests_SoundSet_Quick",
    "QuestSoundSetToggle": "CRDTN_Quests_SoundSet_Toggle_Paper"
}
```
````

Create an empty config file in **$profiles/CRDTN/Quests/Quests.json**

{% code title="quests.json" lineNumbers="true" fullWidth="false" %}

```json
{
  "Quests": [],
  "QuestGivers": []
}
```

{% endcode %}

### Examples

Download examples of the config files if you need

{% file src="/files/etIGxmgGDZVmhrho2TEn" %}

{% file src="/files/0yyOtCZQQZuALtDfZ3rl" %}

{% file src="/files/0Qei3P3uBs7qnKX9VTqP" %}

{% file src="/files/pnIM6kg0PEYanB20tHRo" %}

{% file src="/files/lcHl6Inyq2pTcj2E8vO4" %}

{% file src="/files/QA6WecTZStWP329EmCqe" %}
Quests.json
{% endfile %}


# Quests.json

Main config file of the quest database

This json file has two objects&#x20;

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FLlrYROjC2lqaEK1Coine%2Fimage.png?alt=media&amp;token=819006c8-1fc4-4bac-8390-48c68e19f869" alt=""><figcaption><p>Empty quests.json</p></figcaption></figure>

* Quests - An array of the [#quest-object-you-can-add-multiple-of-these](#quest-object-you-can-add-multiple-of-these "mention")
* QuestGivers - An array of Quest Givers&#x20;
  * Refer to the example file

## Quest Object

````json
```json
{
  "Id": "uniqueIdOfQuest",
  "TakerId": "uniqueIdOfQuestTaker",
  "QType": 1,
  "Name": "Quest example name",
  "Description": "Description goes here",
  "Goals": [],
  "Rewards": [],
  "IsRepeatable": false,
  "PreQuests": 
    [
      "id1", 
      "id2", 
      "id3" 
    ],  
  "RepeatDurationHours": 0,
  "RepeatDurationMinutes": 1,
  "EventId": "unqiue_id_of_event",
  "EventSendToClient": false,
  "ResetKillsComplete": true,
  "ShowGoalItems": false,
  "ShowRewardItems": false
}
```
````

####

<table><thead><tr><th>Parameter</th><th>Meaning</th><th>Values</th></tr></thead><tbody><tr><td>Id</td><td>Unique identifier of the quest. Make sure there is always only one unique id of the quest.</td><td></td></tr><tr><td>TakerId</td><td>Unique identifier of the taker id. Explained later</td><td></td></tr><tr><td>QType</td><td>Numerical identifier of the quest type</td><td><pre><code>0	_NONE,
1	TURN_IN,
2	KILL,
3	EXPLORE,
4	TRADE,
5	CRAFT,
6	ACTION
</code></pre></td></tr><tr><td>Name</td><td>Name of the quest displayed in the quest list</td><td>You can use stringtable<br><code>#someKey</code></td></tr><tr><td>Description</td><td>Description of the quest displayed in the contnt menu of the quest log</td><td></td></tr><tr><td>Goals</td><td>Goal object definition</td><td><a href="/mods/crdtn-quests/server-side/installation/quests-json/goal">MORE INFO HERE</a></td></tr><tr><td>Rewards</td><td>Reward object definition</td><td><a href="/mods/crdtn-quests/server-side/installation/quests-json/reward">MORE INFO HERE</a></td></tr><tr><td>IsRepeatable</td><td>Boolean value representing the repeatability of quest</td><td><code>true</code> x <code>false</code></td></tr><tr><td>PreQuests</td><td>Array of string ids of different quests which need to be completed before displaying this quest in the list</td><td><code>["idOfQuest1", "idOfQuest2"]</code></td></tr><tr><td>RepeatDurationHours</td><td>Integer value of hours representing, when the quest is available to take again.</td><td></td></tr><tr><td>RepeatDurationMinutes</td><td>Integer value of hours representing, when the quest is available to take again.</td><td></td></tr><tr><td>EventId</td><td>Unique identifier</td><td><a href="/mods/crdtn-quests/server-side/installation/quest-events">MORE INFO HERE</a></td></tr><tr><td>EventSendToClient</td><td>Boolean value representing the passing of logic on the client when the quest is completed.</td><td><a href="/mods/crdtn-quests/server-side/installation/quest-events">MORE INFO HERE</a></td></tr></tbody></table>

####


# Goal

````json
```json
 {
          "QType": 5,
          "ClassName": "Rag",
          "State": false,
          "Count": 2,
          "Quantity": 0,
          "Value": "",
          "TriggerCoordinate": "",
          "TriggerRadius": 0.0,
          "TriggerId": "",
          "TriggerEventId": "",
          "TriggerSendToClient": false,
          "Description": "Gather ",
          "KeepItem": false
        }
```
````

<table data-full-width="true"><thead><tr><th width="206">Parameter</th><th width="274.6666666666667">Meaning</th><th>Values</th></tr></thead><tbody><tr><td>QType</td><td>Numerical identifier of the quest type</td><td><pre><code>0	_NONE,
1	TURN_IN,
2	KILL,
3	EXPLORE,
4	TRADE,
5	CRAFT,
6	ACTION
</code></pre></td></tr><tr><td>ClassName</td><td>Class type of the item, action, part of the name of npc</td><td><p></p><pre class="language-csharp"><code class="lang-csharp"><strong># Action
</strong><strong>ActionDrinkWellContinuous
</strong># Item
HandDrillKit
# NPC - Zombie, animal
# You can use prefix in the class name
Zmbf_

</code></pre></td></tr><tr><td>State</td><td>Boolean representing the progression</td><td>make always false and forget about this value</td></tr><tr><td>Count</td><td>integer value of required amount </td><td><strong>USE ONLY ONE  !!</strong></td></tr><tr><td>Quantity</td><td>integer value of required quantity </td><td><strong>NEVER USE BOTH !!</strong></td></tr><tr><td>Value</td><td>string value for special value</td><td></td></tr><tr><td>TriggerCoordinate</td><td>string coordinate value </td><td>"0 0 0" </td></tr><tr><td>TriggerRadius</td><td>float value of radius</td><td>10.0</td></tr><tr><td>TriggerId</td><td>unique identifier of the trigger</td><td>Server determines the spawning of triggers based on the player count and if there is a player who has a certain quest which requires this trigger.</td></tr><tr><td>TriggerEventId</td><td></td><td>MORE INFO HERE</td></tr><tr><td>TriggerSendToClient</td><td></td><td></td></tr><tr><td>Description</td><td>Brief description of the goal</td><td></td></tr><tr><td>KeepItem</td><td>Boolean flag which says, whether to keep the item in the player's inventory upon the quest completion. </td><td>true/false</td></tr></tbody></table>


# Reward


# Quest Events

Quest events are one of the most amazing features of this system and it allows you to add fully custom logic happening around the world after quests are being completed. You can either trigger the EVR on Namalsk, or change weather, spawn creatures, items, explosions, whatever you want.&#x20;

There are two types of Quest Event Handlers

* QuestEventHandlerServer
  * This is responsible for triggering the logic upon completion on the server side. Spawning creatures, objects and changing the game environment should be done here so everything is synchronized to the other players. As you might remember, in the [Quest](/mods/crdtn-quests/server-side/installation/quests-json)/[Goal](/mods/crdtn-quests/server-side/installation/quests-json/goal) definition, the parameter  **"TriggerSendToClient": false**
  * This paramater does the passing of an information, that the event should also happen on the client.&#x20;
  * **IMPORTANT -** it doesn't mean, that this logic is the same on client
* QuestEventHandlerClient
  * You can specify additional logic like post processing changes, specifically sounds and other things you can do on the client only.&#x20;
  * Sound for example

    <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FnOboL3RKqfOXeaZhhee0%2Fimage.png?alt=media&amp;token=6e43cae9-989c-4a5b-be43-a7469b0bf8f4" alt=""><figcaption><p>You can invoke sounds by calling <strong>CRDTN_PluginBase.CRDTN_PlaySound("SOUNDSET", GetGame().GetPlayer());</strong></p></figcaption></figure>

#### EXAMPLE OF THE TELEPORTATION TRIGGER

This trigger teleports a player to a certain location when completing the quest. You can see the event key `test_quest_complete` which has to be in the quest definition at parameter&#x20;

````csharp
```c
modded class QuestEventHandlerServer
{
    override void OnQuestEvent(PlayerBase questCompleteActor, Quest questDefinition, string eventKey, ref Param params = NULL, ref PlayerIdentity identity = NULL, ref Object target = NULL, bool sendToClient = true)
    {
        if (questCompleteActor == NULL || eventKey == "")
        {
            return;
        }

        // Event triggered by the explore trigger in the quest
        // THIS EVENT KEY NEEDS TO BE IN THE QUEST DEFINITION
        if (eventKey == "test_quest_complete")
        {
            questCompleteActor.SetPosition("9817.386719 250.825714 11459.413086");
        }

        super.OnQuestEvent(questCompleteActor, questDefinition, eventKey, params, identity, target, sendToClient);
    };
};
```
````

Make sure you check the examples in the package. If you're still not sure what is this about. Do not hesitate to ask on the discord.&#x20;


# Teleport quest with quest event (server)

#### Quest

````json5
```json
{
      "Id": "TestQuest",
      "TakerId": "player",
      "QType": 1,
      "Name": "Test quests",
      "Description": "Complete this quest to teleport to testing area of the quests. This quest uses regular Turn In goal and server events to teleport the player to a location after completion. You can follow up in the config file and respective classes to do something similar.",
      "Goals": [
        {
          "QType": 1,
          "ClassName": "",
          "State": true,
          "Count": 0,
          "Quantity": 0,
          "Value": "",
          "TriggerCoordinate": "",
          "TriggerRadius": 0.0,
          "TriggerId": "",
          "TriggerEventId": "",
          "TriggerSendToClient": false,
          "Description": "Teleport me",
          "KeepItem": false
        }
      ],
      "Rewards": [],
      "IsRepeatable": false,
      "PreQuests": [],
      "RepeatDurationHours": 0,
      "EventId": "test_quest_complete",
      "EventSendToClient": true
    }
```
````

#### QuestEventHandlerServer

Always make sure, that you put server based quest event handlers on the server side mod only. It's part of the&#x20;

````c
```c
modded class QuestEventHandlerServer
{
    override void OnQuestEvent(PlayerBase questCompleteActor, Quest questDefinition, string eventKey, ref Param params = NULL, ref PlayerIdentity identity = NULL, ref Object target = NULL, bool sendToClient = true)
    {
        if (questCompleteActor == NULL || eventKey == "")
        {
            return;
        }
        // Event triggered by the explore trigger in the quest
        if (eventKey == "test_quest_complete")
        {
            questCompleteActor.SetPosition("9817.386719 250.825714 11459.413086");
        }
        super.OnQuestEvent(questCompleteActor, questDefinition, eventKey, params, identity, target, sendToClient);
    };
};
```
````

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FELQgY1QrOTdNF6R6lGSh%2Fimage.png?alt=media&amp;token=f6756ac6-8f09-44ae-a387-fa67fa74740c" alt=""><figcaption></figcaption></figure>


# Quest & Goal Types

### Types

<div><figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FdskhwVi9yVI3yDx6TSuA%2F74.png?alt=media&amp;token=f2c00a05-b61b-4f70-b0d3-8aebb41e24b9" alt=""><figcaption><p>Turn In</p></figcaption></figure> <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2Fq8ehfLflnAJHLIZci88t%2F51.png?alt=media&amp;token=ec4bacbb-5d2f-4cfe-8f7a-c0f5440f2122" alt=""><figcaption><p>Kill</p></figcaption></figure> <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FvSfc6Mp5QhzXE0ZHLEml%2F50.png?alt=media&amp;token=1e416843-ac9a-4191-b843-f5129c3018f9" alt=""><figcaption><p>Explore</p></figcaption></figure> <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2F6iHAKIa5kam3TyhvOBQJ%2F93.png?alt=media&amp;token=7297d5c3-b9d1-4b01-8e1c-ebf4c99d0c06" alt=""><figcaption><p>Action</p></figcaption></figure> <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FvZ7GKyjbSgeXUaIv9Pwp%2F82.png?alt=media&amp;token=f172a84c-b407-4c3f-8aec-b355f0de4d55" alt=""><figcaption><p>Craft</p></figcaption></figure> <figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FoNsxdhQ1Psr5H3U5Own2%2F75.png?alt=media&amp;token=0ee7d313-ce77-4405-89da-20b7de14dcfd" alt=""><figcaption><p>Trade</p></figcaption></figure></div>

System allows to setup the various types of quests and goals.&#x20;

### Quest

Quest is a wrapper of goals, it defines the whole name and description of the full context of goals contained in the quest. You can setup various types of goals for certain quest. The quest type is more responsible for the visual appearence in the quest log so you can choose between the types above to distinguish it by the icon.&#x20;

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FSsr06sJaqbbb2TN9yqv6%2Fimage.png?alt=media&amp;token=9313f394-e3bc-4827-9b52-34db8c3298d7" alt=""><figcaption><p>List of entries - this image is from a list of various entries in the menu. It's just a showcase of the variability of look</p></figcaption></figure>

### Goal Types

{% content-ref url="/spaces/7r6RseTZTkJJcKqbC3EI/pages/Q24YSIfwIosB2Ly18G1M" %}
[Turn-In goal](/mods/crdtn-quests/server-side/quest-and-goal-types/turn-in-goal)
{% endcontent-ref %}

Turn in is classical talk to type of quest and can be used for a simple interaction with object or another NPC.&#x20;

{% content-ref url="/spaces/7r6RseTZTkJJcKqbC3EI/pages/OYJXRUWsrYJmOvubwBzJ" %}
[Kill goal](/mods/crdtn-quests/server-side/quest-and-goal-types/kill-goal)
{% endcontent-ref %}

Kill goal as the name says, it's about killing the targets, you can specify animals, zombies or other NPCs if you use some kind of an AI mod.&#x20;

{% content-ref url="/pages/jMFPSspZA0LTOhfEdLQ2" %}
[Explore goal](/mods/crdtn-quests/server-side/quest-and-goal-types/explore-goal)
{% endcontent-ref %}

Exploration quests and goals can be used for discovery and leading the player to certain locations. Once the player reaches the specified location, the respective object is triggered on the server and with additional code, you can also call various functions and events after reaching a certain locations.&#x20;

{% content-ref url="/pages/HeqO9AjgvKSVqTFqPZb5" %}
[Trade goal](/mods/crdtn-quests/server-side/quest-and-goal-types/trade-goal)
{% endcontent-ref %}

Trade is for the type of quest, where you need to deliver something in order to get some reward. But it's more of a fancy way of naming and visual distinguish. You can always setup various rewards in different quests.&#x20;

{% content-ref url="/pages/cCKvhritO0vIWStA7paW" %}
[Craft goal](/mods/crdtn-quests/server-side/quest-and-goal-types/craft-goal)
{% endcontent-ref %}

Crafting goal is more of a placeholder type and can be used for crafting so for example if you want to explain a player various recipes and ways how to craft specific items. You can setup multiple goals which requires certain amount of items and in reward, you can get the desired item as result of recipe.

### For adding the quest giver into world, follow up here&#x20;

[Quest NPCs](/mods/crdtn-quests/server-side/quest-npcs)


# Turn-In goal

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FdskhwVi9yVI3yDx6TSuA%2F74.png?alt=media&amp;token=f2c00a05-b61b-4f70-b0d3-8aebb41e24b9" alt="" width="128"><figcaption><p>Turn In Quest Icon</p></figcaption></figure>

Repeatable turn-in quest. This quest is completed right after taking.&#x20;

```json
{
      "Id": "repeatable",
      "TakerId": "lesnik",
      "QType": 1,
      "Name": "Repeatable quest",
      "Description": "This quest can be repeated every 4 hours.",
      "Goals": [
        {
          "QType": 1,
          "Description": "Talk to "
        }
      ],
      "Rewards": [
        {
          "RewardType": 1,
          "ClassName": "TF_Ammo_57",
          "Amount": 1
        }
      ],
      "IsRepeatable": true,
      "PreQuests": [],
      "RepeatDurationHours": 4
}
```


# Kill goal

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2Fq8ehfLflnAJHLIZci88t%2F51.png?alt=media&amp;token=ec4bacbb-5d2f-4cfe-8f7a-c0f5440f2122" alt="" width="128"><figcaption><p>Kill Quest Icon</p></figcaption></figure>

As you can see, I use ClassName field to define a target to kill. You can use just a part of the classname like I do for the zombies. If you put `Zmb`, it means that it will register all the kills of entities starting with a class name Zmb\*\*\*\*\*.&#x20;

If you want to be more restrictive, you can always put an exact classname like `ZmbF_CitizenANormal_Blue`

```json
{
    "Id": "killQuest",
    "TakerId": "player", 
    "QType": 2,
    "Name": "Kill Quest",
    "Description": "Time has come. You need to kill some zombies.",
    "Goals": [
        {
          "QType": 2,
          "ClassName": "Zmb",
          "Count": 5,
          "Description": "Kill 5 zombies!"
        }
    ],
    "Rewards": [
        {
          "RewardType": 1,
          "ClassName": "AirborneMask",
          "Amount": 1
        }
    ]
}
```


# Trade goal

<div align="left"><figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FsGX44wOQtWPs1ZSFZHcM%2F93.png?alt=media&amp;token=10ebf2ca-0792-40cb-9ad1-894a665e76db" alt="" width="128"><figcaption><p>Trade Quest Icon</p></figcaption></figure></div>

This quest requires to bring *Disinfectant Alcohol, Spray* and *Iodine Tincture*. Each goal has the quantity set. Be careful about these numbers and make sure, what is the real quantity of the item.&#x20;

This quest is not **repeatable**

This quest has a pre-quest of id `player1`

You will get reward - 1x *cooking pot* and 1x *baked beans can*

```json
{
      "Id": "medicineTrading",
      "TakerId": "barman",
      "QType": 4,
      "Name": "Medicine deal",
      "Description": "Trade medicine",
      "Goals": [
        {
          "QType": 4,
          "ClassName": "DisinfectantAlcohol",
          /* "Count" : 0 */ // 
          "Quantity": 100, // Use Quantity if the item has quantity 
          "Description": "Bring " // Rest is filled automatically by display name 
        },
        {
          "QType": 4,
          "ClassName": "DisinfectantSpray",
          "Quantity": 100,
          "Description": "Bring "
        },
        {
          "QType": 4,
          "ClassName": "CrudeMachete",
          "Count": 1,
          "Description": "Bring "
        }
      ],
      "Rewards": [
        {
          "RewardType": 1,
          "ClassName": "Pot",
          "Amount": 1
        },
        {
          "RewardType": 1,
          "ClassName": "BakedBeansCan",
          "Amount": 1
        }
      ],
      "IsRepeatable": false,
      "PreQuests": [
        "player1"
      ],
      "RepeatDurationHours": 0
}

```


# Craft goal

<figure><img src="https://3957347284-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7r6RseTZTkJJcKqbC3EI%2Fuploads%2FvZ7GKyjbSgeXUaIv9Pwp%2F82.png?alt=media&amp;token=f172a84c-b407-4c3f-8aec-b355f0de4d55" alt="" width="128"><figcaption><p>Crafting Quest Icon</p></figcaption></figure>


# Action goal


# Explore goal

If the **TakerId** is `player`, the quest will be available in the player's questlog. But do not forget to add `player` into the `QuestGivers` object in `Quest.json`

Trigger ID field is used for the server side register of the trigger object spawned in the world. This ID needs to be unique so the server side script is able to handle removal and spawn of these triggers.&#x20;

```json

{
      "Id": "exploreQuest1",
      "TakerId": "player",
      "QType": 3,
      "Name": "Explore Quest",
      "Description": "Explore the zone",
      "Goals": [
        {
          "QType": 3,
          "TriggerCoordinate": "8836.527344 2.380000 2293.031250",
          "TriggerRadius": 50.0,
          "TriggerId": "bridge",
          "Description": "Explore "
        }
      ],
      "Rewards": [
        {
          "RewardType": 1,
          "ClassName": "Thermometer",
          "Amount": 3
        }
      ],
      "IsRepeatable": false,
      "PreQuests": [],
      "RepeatDurationHours": 0
}
```


# Rewards


# Quest NPCs

You can spawn custom NPC through a built in utility in the quest system or spawn your own, or whatever else NPCs from different mods. I suggest Talking NPCs for example.&#x20;

{% code title="NPCs.json" overflow="wrap" %}

````cpp
```json
{
    "SpawnLocations": [],
    "NpcLocations": [
        {
            "Name": "Starting Village - Guard",
            "Coordinate": [6238.8403, 17.084, 11803.018],
            "Orientation": [4.375, 0.0, 0.0],
            "ClassName": "CRDTN_SurvivorM_Denis",
            "NpcName": "Test_Denis",
            "GiverId": "CRDTN_SurvivorM_Denis",
            "Clothes": [
                "MilitaryBoots_Bluerock",
                "Winter_Parka_Green",
                "CRDTN_PlateVest_Svoboda",
                "GorkaHelmet_Black",
                "WoolGloves_Green",
                "Spur_CamelBag_Green",
                "NBCPantsGray",
                "AirborneMask"
            ],
            "EquipInHands": {
                "ClassName": "CRDTN_AK74_BLUE",
                "Slot": "Hands",
                "Attachments": [
                    {
                        "ClassName": "AK_Suppressor",
                        "Slot": "",
                        "Attachments": []
                    },
                    {
                        "ClassName": "AK_WoodBttstck_Camo",
                        "Slot": "",
                        "Attachments": []
                    },
                    {
                        "ClassName": "AK_WoodHndgrd_Camo",
                        "Slot": "",
                        "Attachments": []
                    },
                    {
                        "ClassName": "Mag_AK74_45Rnd",
                        "Slot": "",
                        "Attachments": []
                    }
                ]
            }
        },
        {
            "Name": "Starting Village - Quest Giver",
            "Coordinate": [6240.485840, 17.084372, 11799.670898],
            "Orientation": [90.0, 0.0, 0.0],
            "ClassName": "CRDTN_SurvivorF_Gabi",
            "NpcName": "Test_Gabi",
            "GiverId": "CRDTN_SurvivorF_Gabi",
            "Clothes": [
                "MilitaryBoots_Bluerock",
                "Winter_Parka_White",
                "Mp133Shotgun",
                "WoolGloves_Green",
                "NBCPantsGray"
            ],
            "EquipInHands": {}
        }
    ]
}
```
````

{% endcode %}


# CRDTN Fire Regen

Discover a haven amidst the wastelands! Introducing a simple yet powerful addition to your game: the Fire Heal Modifier. Seek out a secure spot, ignite a fire, and find solace near the warmth of an oven. Experience the thrill of quicker rejuvenation, surpassing the challenges of the desolate wilderness.

This mod does not have any requirements to setup. It's one of those more simple mods which you just need to add to your modlist. :thumbsup:

**Functionality:**

* Small server side mod (no need for clients to download)
* Config file for the unique settings
* Regeneration of HP or BLOOD when being nearby a fireplace
* Can be restricted only to indoor fire places
* Can be restricted to Hunger and Thirst levels

**Thresholds:**

* GREAT = 0&#x20;
* HIGH = 1&#x20;
* MEDIUM = 2&#x20;
* LOW = 3&#x20;
* CRITICAL = 4

{% embed url="<https://www.youtube.com/watch?v=QfnUuSogRkw>" %}
ver 1.0
{% endembed %}

{% embed url="<https://youtu.be/4F_gDzhTjfo>" %}

Steam Workshop Link <https://steamcommunity.com/sharedfiles/filedetails/?id=3003546953>


# Config

This mod is really simple and it can be a nice showcase, how to add a new modifier to the game.&#x20;

#### If you want to add a new modifier, you need to extend an enum of *eModifiers*

*Code is available on* [*github*](https://github.com/freeman1992/fox-crdtn-fire-regen)

#### Default config file&#x20;

Upon starting the server, the config is created in `$profiles/CRDTN/FireRegen/World.json`

```c
float HealRadius                            = 2;        // Radius in meters
float HealTreshold                          = 100;
float BloodTreshold                         = 5000;
EStatLevels HungerThreshold                 = 1;        // GREAT - 0, HIGH - 1, MEDIUM - 2, LOW - 3, CRITICAL - 4
EStatLevels ThirstThreshold                 = 1;        
float HealthRatePerTick                     = 0.25;     // Amount of stat add/subtract per TickIntervalActive
float BloodRatePerTick                      = 0.25;
bool IndoorOnly                             = true;     // If false, works on every fireplace object
float TickIntervalInactive                  = 10.0;
float TickIntervalActive                    = 10.0;
// All notifications can be left blank "" so they are not displayed within the game
string NotificationHealEnded                = "Goodbye my lovely fireplace!";    // A notification displayed when leaving the fireplace or the effect stops
string NotificationHealStarted              = "Ho Ho Ho... I'm getting much better now.";    // A notification displayed upon start
string NotificationHungerAndThirst          = "Player is too hungry or thirsty to heal";    // Shown when player is not elligible for the regen
string NotificationHealthIncrement          = "Player's health is increasing";             // Shown per tick
string NotificationBloodIncrement           = "Player's blood is increasing";                // Shown per tick
string NotificationHealthReached            = "Player's health is full";                    // When filled the stat
string NotificationBloodReached             = "Player's blood is full";                    // When filled the stat
```

{% code title="World.json" overflow="wrap" %}

```c
{
    "HealRadius": 10.0,
    "HealTreshold": 100.0,
    "BloodTreshold": 5000.0,
    "HungerThreshold": 1,
    "ThirstThreshold": 1,
    "HealthRatePerTick": 10.0,
    "BloodRatePerTick": 10.0,
    "IndoorOnly": 0,
    "TickIntervalInactive": 10.0,
    "TickIntervalActive": 2.0,
    "NotificationHealEnded": "Goodbye my lovely fireplace!",
    "NotificationHealStarted": "Ho Ho Ho... I'm getting much better now.",
    "NotificationHungerAndThirst": "Player is too hungry or thirsty to heal",
    "NotificationHealthIncrement": "Player's health is increasing",
    "NotificationBloodIncrement": "Player's blood is increasing",
    "NotificationHealthReached": "Player's health is full",
    "NotificationBloodReached": "Player's blood is full"
}

```

{% endcode %}


# CRDTN Sounds

This simple mod replaces most of the vanilla foley sounds and adds additional flavor to the game by changing some of the weapon sounds. Also adds inventory sounds when a player moves with a certain items. Currently they are categorized and some of the sounds can be configure explicitely to provide unique experience when you get stuck at your inventory management.&#x20;

Steam Workshop Link: <https://steamcommunity.com/sharedfiles/filedetails/?id=2900865153>


# CRDTN Locked Doors

Fastest way of setting up the locked buildings on the server

Introducing the cutting-edge "Locked Doors" mod for DayZ, a game-changer for server owners seeking to elevate their players' survival experience. This innovative modification empowers administrators to implement unyielding static locks on the doors of the DayZ structures.

Set notifications that keep players informed, making each lock-picking attempt a strategic endeavor.

### Features

* Locks on the static objects, vanilla buildings whatever has door proxy object
* Custom sounds synced between clients and distance based doppler effect
* Custom keys for each door or groups

## History of the development&#x20;

With this simple idea came my friend **Sajid**, who asked me, whether I could make a mod for the locking of doors in the map. He gave me the models and I made a working prototype in matter of hours.&#x20;

It took long to publish but I had to do other things as well.&#x20;

## How it works

Spawn an Admin Lockpick, go to the door object and lock it. Done :smile: The config file is auto generated and you can just tweak the values based on your needs.&#x20;

You can have various admin lockpicks which automatically adds Key types to the config.&#x20;

{% embed url="<https://youtu.be/KzQxguMhcGs>" %}

## Workshop


# Config

Explanation of the config structure

<table data-full-width="true"><thead><tr><th width="259">Parameter</th><th width="427.6666666666667">Meaning</th><th>Values</th></tr></thead><tbody><tr><td>notificationIcon</td><td>Path to the icon used in the notification</td><td>string</td></tr><tr><td>sendNotificationToAll</td><td>Flag whether to send a notification to all players upon unlocking</td><td>1 / 0 in string format</td></tr><tr><td>isAlarmed</td><td>Flag whether to play alarm sound on the object. </td><td>1 / 0 in string format</td></tr><tr><td>actionText</td><td>Text showing on the contextual action tooltip when holding the key</td><td>string</td></tr><tr><td>notificationText</td><td>Actual text shown in the notification</td><td>string</td></tr><tr><td>sendNotificationToClient</td><td>Flag whether to send a notification to the client actor</td><td>1 / 0 in string format</td></tr><tr><td>notificationHeader</td><td>Text of the notification header</td><td>string</td></tr><tr><td>alarmSound</td><td>Sound set of the sound being played upon unlocking. If the isAlarmed is set to "1"</td><td>string</td></tr><tr><td>unlockTime</td><td>Duration of the unlocking process</td><td>integer value in string </td></tr></tbody></table>

## Keys

If you want to setup multiple keys for the doors, you can specify multiple class types of the keys.&#x20;

It's very important to inherit from class - `CRDTN_Key_Base`

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "m_DoorConfig": {
        "Land_Mil_Barracks4": [
            {
                "DoorIndex": 3,
                "BuildingPosition": [
                    -1,
                    -1,
                    -1
                ],
                "BuildingClassname": "Land_Mil_Barracks4",
                "KeyClassnames": [
                    "CRDTN_Key_Universal"
                ],
                "Data": {
                    "notificationIcon": "set:ccgui_enforce image:MapUserMarker",
                    "sendNotificationToAll": "0",
                    "isAlarmed": "1",
                    "actionText": "Unlock with key",
                    "notificationText": "Door unlocked",
                    "sendNotificationToClient": "0",
                    "notificationHeader": "ALERT",
                    "alarmSound": "CRDTN_Core_SoundSet_Sound_Alarm",
                    "unlockTime": "10"
                }
            }
        ]
    }
}
</code></pre>

This config file setup all the military buildings of type `Land_Mil_Barracks4` and its door on the index 3 to be locked. You can use only CRDTN\_Key\_Universal to unlock.&#x20;


# How To

Mod the Locked Doors? You need to create a new config.cpp file and add it somewhere within your server mods.

## New admin lockpick (inherit from CRDTN\_AdminLockPick)

{% code fullWidth="false" %}

```cpp
class AdminLockPick_NewOfYourChoice : CRDTN_AdminLockPick
{
    displayName = "Universal Admin Lockpick - Whatever";
    keys[] = {"MyVeryCoolKey"};
    descriptionShort = "Description goes here";
};
```

{% endcode %}

## New key (inherit from CRDTN\_Key\_Base)

```cpp
class MyVeryCoolKey : CRDTN_Key_Base
{
    scope = 2;
    displayName = "My very cool key";
    descriptionShort = "Modded key to unlock new types of doors I use.";
};
```

If you follow the instructions and will use something like above, when you use the `AdminLockPick_NewOfYourChoice` on the doors, it will automatically generate the config object for the certain doors on that particular location.&#x20;

## Extending your current keys / cards and using keys from other mods

I cannot guarantee the others mods will work properly because people are doing a lot of things differently.&#x20;

But it should be able to use your own cards/keys by just extending the class by my base class. There are basically 2 approaches:&#x20;

* Set the actions on your class
* Inherit from my base class&#x20;

```csharp
// Add Actions
override void SetActions()
{
    super.SetActions();
    AddAction(CRDTN_ActionUnlockLockedDoor);
}

// Inherit your class from CRDTN_LockedDoors_ItemBase
class YOUR_NEW_CLASSTYPE : CRDTN_LockedDoors_ItemBase {};

```


# config.cpp

```csharp
class CfgPatches
{
    class CRDTN_LockedDoors
    {
        units[] = {""};
        weapons[] = {};
        requiredVersion = 0.1;
        requiredAddons[] = {"DZ_Data", "DZ_Scripts", "CRDTN_Core"};
        defines[] = {"CRDTN_LockedDoors"};
    };
};

class CfgMods
{
    class CRDTN_LockedDoors
    {
        name = "CRDTN Locked Doors";
        credits = "SajidAlfa models, Freeman code";
        author = "freeman@foxapo.com";
        type = "mod";
        dependencies[] = {"Game", "World", "Mission"};
        dir = "CRDTN_LockedDoors";
        class defs
        {
            class gameScriptModule
            {
                value = "";
                files[] = {"CRDTN_LockedDoors/Scripts/3_Game"};
            };
            class worldScriptModule
            {
                value = "";
                files[] = {"CRDTN_LockedDoors/Scripts/4_World"};
            };
            class missionScriptModule
            {
                value = "";
                files[] = {"CRDTN_LockedDoors/Scripts/5_Mission"};
            };
            class imageSets
            {
                files[] = {};
            };
        };
    };
};

class CfgVehicles
{

    class Inventory_Base;
    class Lockpick : Inventory_Base {};

    class CRDTN_LockedDoors_ItemBase : Inventory_Base
    {
        scope = 0;
    };

    class CRDTN_Card_LockedDoors : CRDTN_LockedDoors_ItemBase
    {
        scope = 0;
        hiddenSelections[] = {"zbytek"};
        model = "CRDTN_LockedDoors\Models\key\key.p3d";
        itemSize[] = {1, 2};
        weight = 100;
    };

    class CRDTN_Key_LockedDoors : CRDTN_LockedDoors_ItemBase
    {
        scope = 0;
        hiddenSelections[] = {"zbytek"};
        itemSize[] = {1, 1};
        weight = 100;
        model = "CRDTN_LockedDoors\Models\key\key.p3d";
    };

    /// @brief BASE CLASS FOR THE KEYS
    class CRDTN_Key_Base : CRDTN_Key_LockedDoors
    {
        scope = 2;
        displayName = "";
        descriptionShort = "";
        hiddenSelectionsTextures[] = {"CRDTN_LockedDoors\Models\key\data\Key_black.paa"};
        stackedUnit = "pc.";
        quantityBar = 1;
        canBeSplit=0;
        weight = 20;
        varQuantityInit = 1;
        varQuantityMin = 0;
        varQuantityMax = 1;
        varQuantityDestroyOnMin = 1;
        destroyOnEmpty = 1;
        weightPerQuantityUnit = 0.0;
    };

    class CRDTN_Card_Base : CRDTN_Card_LockedDoors
    {
        scope = 2;
        displayName = "";
        descriptionShort = "";
        hiddenSelectionsTextures[] = {"CRDTN_LockedDoors\Models\key\data\Key_black.paa"};
    };

    // TYPES
   
    class CRDTN_AdminLockPick : Lockpick
    {
        scope = 2;
        displayName = "Admin Lockpick";
        keys[] = {"CRDTN_KeyMaster"};
    };

    class CRDTN_AdminLockPick_PoliceStation : CRDTN_AdminLockPick
    {
        displayName = "Police Station Admin Lockpick";
        keys[] = {"CRDTN_Key_Universal_PoliceStation"};
        descriptionShort = "This key locks the door and sets the config to use the universal police station key";
    };

    class CRDTN_AdminLockPick_Medical : CRDTN_AdminLockPick
    {
        displayName = "Medical Admin Lockpick";
        keys[] = {"CRDTN_Key_Universal_Medical"};
        descriptionShort = "This key locks the door and sets the config to use the universal medical key";
    };

    class CRDTN_AdminLockPick_Universal : CRDTN_AdminLockPick
    {
        displayName = "Universal Admin Lockpick";
        keys[] = {"CRDTN_Key_Universal"};
        descriptionShort = "This key locks the door and sets the config to use the universal key";
    };

    class CRDTN_KeyMaster : CRDTN_Key_Base
    {
        scope = 2;
        displayName = "Skeleton key";
        descriptionShort = "Can open any door in Chernarus.";
    };

    class CRDTN_Key_Universal : CRDTN_Key_Base
    {
        scope = 2;
        displayName = "Universal key";
        descriptionShort = "This key unlocks most of the common door locks across Chernarus.";
        hiddenSelectionsTextures[] = {"CRDTN_LockedDoors\Models\key\data\Key_blue.paa"};
    };
    class CRDTN_Key_Universal_PoliceStation : CRDTN_Key_Base
    {
        scope = 2;
        displayName = "Police Station Key";
        descriptionShort = "Special security key used by the police of Chernarus.";
    };
    class CRDTN_Key_Universal_Medical : CRDTN_Key_Base
    {
        scope = 2;
        displayName = "Medical Key";
        descriptionShort = "Special security key used by medical services from Chernarus";
    };
};
```


