Jump to content

DML - Mission Creation Toolbox [no Lua required]


Recommended Posts

Version 0.992 - 20220310

Feature Update: Unit Zone, "Island Defender" full mission

It surely took some time. Believe it or not, we now finally have Trigger Zones in DML that work as triggers! Yay - groundbreaking tech! Since they are DML, they fully support DML flags, so you can now trigger - the right way - flags and modules when something enters or exits a zone.

image.png

DML really shines here: you can edit the attributes right there in the zone, making trigger zones really comfortable to use, and much easier to understand - no longer do you have to sift through game triggers and compare flag numbers. The attributes can trigger named flags, right there on the zone, and support wildcard group / player unit names!

image.png

Also part of this release is an early version of ‘Island Defenders’, a full multiplayer scenario built entirely with DML that serves both as show case for DML’s capabilities (randomization, win condition, CSAR support, single-use, etc. - without a single line of Lua), and as a demo use case as it shows how many of the various modules work together to create an engaging and fun (if difficult) mission. Look for a discussion on its build  in one of the upcoming releases. Island Defenders itself will also be released as a stand-alone mission so you don’t have to download DML to get access to it

image.png

As always there are also minor updates to other modules, and those who are interested may even find a glimpse of xFlags, the flag transmogrifier module that will be released later.

 

CHANGES

Documentation
    - follow me! demo documentation
    - unit zone reference 
    
Demos
    - follow me! (message and unitZone)
    - (full MP scenario) Island Defender

Modules 
    - unitZones 1.0.0
    - xFlags (pre-release)

Other 
    - cfxZones 2.5.8
    - countDown 1.2.1
    - messenger 1.1.1

 

Enjoy, 

-ch

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

3 hours ago, RubberDogSh1tOutOfHKG said:

How does the Civ-Traffic work?

CivAir is a drop-in module that generates 'civillian' (neutral, non-military) air traffic between airports and works all by itself. You control which airports generate traffic with a simply config zone. Documentation for that module is still on my to-do list, though. 

 

  • Like 1
Link to comment
Share on other sites

Hello.

Without me to read anything yet (i've just dload it) i have a question:

If a group is dead, you just use a template to clone it as a new one ?


Edited by ADHS

Democracy was already invented, while Scrat was eating oak fruits.

Link to comment
Share on other sites

1 hour ago, ADHS said:

If a group is dead, you just use a template to clone it as a new one ?

Pretty much, yes - DML cloners work like this:

  • In ME you put a zone over the group(s) that you want to become a clone template. On mission start, DML saves all those groups in a template, and removes the group. If you want (by adding the onStart attribute to the zone), a clone is spawned at the beginning of the mission, so it looks exactly as in ME
  • DML uses flags (and supports named flags like "spawnTanks") to signal modules that they should do something. cloners can use a clone? input flag. Every time that the value of that flag changes, the cloner will spawn a fresh clone from the template
  • for convenience, cloners can also watch the last batch of clones it has created. If all of them are destroyed, it can change a flag that you give it with the 'empty!' attribute
  • Of course, if you short-circuit empty! into clone? (by giving the same flag to both), the cloner spawns a new batch if the previously spawned group is dead

Now, DML also has a delayFlag module, that changes the out flag some time after the in flag changes. Put this between the empty! and clone? output/input in your spawner, and the new group spawns after a delay. DML supports stacking of these modules on the same zone, so you can build a stylish self-replenishing cloner in about 30 seconds flat.

Check out the Attack Of the CloneZ demo mission, and perhaps read the corresponding chapter in the doc. And heed the warning: cloners are addictive!

-ch

 


Edited by cfrag
  • Thanks 1
Link to comment
Share on other sites

cfrag

thank you very much for your time and the information in details.

I will start reading tomorrow (baby steps) and once i've started recently to create missions, again, i will be a "headace" 😃

Congratulations for the documentation! Its over than enough for someone who wants to understand how DML works.

I'll come back once i check the demos and try my first attempts/steps.

Thank you 👍


Edited by ADHS

Democracy was already invented, while Scrat was eating oak fruits.

Link to comment
Share on other sites

Version 0.994 - 20220317

Feature Update: groupTracker and CSAR Manager

Another essential piece is in place: groupTracker, a tiny, performance optimized module that simply creates flag events when something happens to the groups that you want to track, has arrived. Although small, deceptively simple and perhaps straight-up boring, it's also incredibly helpful and versatile. A demo mission is available that merely hints at groupTracker's potential. Once you use it, however, you'll wonder how you ever got by without groupTracker - obviously, since tracking group is an essential part of all mission design.

The last release also saw an early release of the (fully fledged) MP mission "Island Defenders". It's currently not mentioned in the documentation because it's not yet done and was updated for this week's release. Documentation may have to wait until after this mission is also released publicly outside of DML

image.png

And lastly, the CSAR Manager module was not just updated to DML flags, it now also has its own fully documented demo, which should allow you to add CSAR capabilities to your own missions in less than five minutes. Next step for CSAR is integration with the PlayerScore module, so anyone can - only if the want - build fun, competitive MP CSAR missions. 
 

Documentation
    - groupTracker documentation
    - groupTracker QuickRef
    - unitZone documentation 
    - CSAR of Georgia documentation 
    - trackThis! documentation 
    - groupTracker QuickRef 

Demos
    - CSAR of Georgia
    - track this!
    - Island Defenders (update)
    
Modules
    - groupTracker 1.0.0

Other Changes     
    - cloneZone 1.3.1
        - groupTracker interface 
        
    - csarManager 2.1.0
        - DML Flags 
        - CSAR Zones update 
        - Config Zone 

    - ssbClient
        - verbosity reduction
        - damager modifier groundwork 
    
    - GuardianAngel 
        - additional checks 
    
    - Guardian Angel Demo 
 

Cheers,

-ch

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Chritian Franz and cf/x AG

thank you. Things are more clear after reading the modules.

For me, syntax, checks, dcs variables/constants etc, weren't clear at all.

Now they are and thank you for your project. I recommend to anyone that want to understand how things work in ME.

1. Is DML support "start from ground + hot" ? or just parking slots ?

2. Is there the ability of "surender" ? Once you prevail and close to be the owner of farp/airport/area, convert the rest of the enemy units to your coalition ?(Idea🙂)


Edited by ADHS

Democracy was already invented, while Scrat was eating oak fruits.

Link to comment
Share on other sites

On 3/18/2022 at 12:41 AM, ADHS said:

Is DML support "start from ground + hot" ? or just parking slots ?

DML's ssbClient and clone zone modules support all starting positions that ME allows planes to take. Other than that I'm not entirely sure what you are asking, but I'd be happy to work it out 🙂 

On 3/18/2022 at 12:41 AM, ADHS said:

Is there the ability of "surender" ? Once you prevail and close to be the owner of farp/airport/area, convert the rest of the enemy units to your coalition

DCS doesn't offer the ability to change a unit's affiliation with a coalition once it has been spawned into the game, so this idea will hit some snags. It should be possible to simply delete all enemy units once you have met all victory conditions. DML currently has no help for that, as it's a pretty straightforward, three-line (maybe 4) code: get all groups for that coalition, iterate and delete them.

Link to comment
Share on other sites

2 hours ago, cfrag said:

DML's ssbClient and clone zone modules support all starting positions that ME allows planes to take.

Ok thank you for clarification.

2 hours ago, cfrag said:

DCS doesn't offer the ability to change a unit's affiliation with a coalition once it has been spawned into the game,

But, airports and farps can do that. Unless they are belong to a different kind of type.

To my question my thinking was if there this option somewhere. Otherwise yes, i can count the remaining enemy number,

type, status etc and after delete them respawn the same for another country.

Democracy was already invented, while Scrat was eating oak fruits.

Link to comment
Share on other sites

Version 0.995 - 20220324

Feature Update: DML Watchflags

image.png

The last big infrastructure piece is now in place, and is slated to be fleshed out for the big "One Oh": Watchflags. They standardize and greatly expand the way that modules work with Input flags, and allow mission builders more finely-grained control over when a flag triggers a module's function. You now can opt to set up additional rules; until now, a module would trigger when a flag changes. This is still their default behavior. Optionally, you now can add rules that narrow this down: for example, you can tell a module that it should only trigger when a flag changes, and if that new value is equal to the number 4. Even better, You can have the module compare it to other flags and only take action if certain conditions are met.

image.png

Over the next few weeks, this capability, together with general DML Flag abilities, is going to be rolled out to all modules that support input/output flags. A new dedicated demo mission with the inspired name "Watchflags demo" is there to, well, demonstrate Watchflags. I hope it shows just how versatile the new trigger methods are. 

Other updates include a hardening of the PlayerScore module against some new, surprising DCS changes that made some previously thought to be safe assumptions (units that are cooking off now switch to static category) unsafe.

And - you may have missed it - last week also saw the release of a new, minor DCS module; some obscure helicopter that uses missiles with the ridiculous name 'Hellfire', I hear. It's been added to the "Island Defender" mission. It's also the reason I got almost nothing done this week.

And here's the skinny on this release:
  
Documentation
    - Watchflags and DML documetation updates 
    - Quickref Update for Watchflags 
    - Watchflag Demo Documentation
    
Modules    
    - Watchflag / DML Flag upgrade 
      - cfxZones 2.6.0
      - messenger 1.2.0
      - rndFlags 1.2.0
      - pulseFlag 1.2.0
      - artilleryZones 2.2.0
      - cloneZones 1.4.0 
      - delayFlags 1.2.0
      - raiseFlag 1.2.0 
      - countDown 1.3.0
      
Demos
    - Watchflags demo
    - Watchflag / DML Flag updates
      - The Zonal Countdown 
      - Pulsing Fun 
      - Attack of the CloneZ
      - Island Defenders
      

Others
    - dcsCommon 2.5.7
    - objectSpawnZones - 1.2.1
    - ArtilleryDemon - 1.0.3
    - PlayerScore - 1.3.1
    - cargoReceiver 1.2.1

 

Cheers,

-ch

 


Edited by cfrag
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

This really seems like a powerful set of tools, and the ability to do everything inside the sim's interface is something that is rather appealing to me!

I've been experimenting with clone zones, and I'm having an odd issue: I'm trying to spawn a group that will re-generate upon destruction as a part of a training mission, and I think I got the clone zone and the timeDelay modules integrated well and they seem to work. However, upon destruction of the group the dead "carcasses" of the vehicles aren't removed, and so continue to clog up the spawn area, with a new vehicle often spawning exactly where a wreck is located since this previous instance didn't move before being destroyed.

The preWipe attribute of the clone zone doesn't seem to do the trick (does it apply only to living units?). Is there a way to accomplish this?

OS: Win11 Pro 64bit MB: ASUS B550-I STRIX CPU: AMD R7 5800X GPU: Nvidia GeForce RTX 2060 Super 8GB RAM: 32GB DDR4 SSD (OS and Sims): Samsung 980 Pro 2TB Accessories: TrackIR5, Warthog HOTAS, CH Pedals

Link to comment
Share on other sites

12 hours ago, Fabri91 said:

The preWipe attribute of the clone zone doesn't seem to do the trick

This appears to be a knock-on effect from one of the recent changes in DCS, where units that are 'cooking off' are now exchanged for static objects and are removed from the group. As a result, when the group is wiped, those static objects aren't removed: they never belonged to the group and DML doesn't know about them. 

Disappointing to say the least. Hopefully there will be a work-around soon. 

  • Like 1
Link to comment
Share on other sites

Version 0.996 - 20220331

Feature Update: QoL Changes

Many modules have received Quality of Life upgrades, making them easier and more comfortable to use. For example, a messenger now can use "<n>" as new line or "<z>" as zone name. The  groupTrackers and cloneZones can pass groups to multiple zones at once, raiseFlag can now also increase or decrease the flag it should raise etc. One particular change also helps to drastically reduce DML-based mission design blues: cfxZones detects when you seemingly forgot to add a "?", "!" or ":" to an attribute name, and will warn you when it starts up. You'll no longer hunt for that Zone where the messengers doesn't fire simply because you accidentally omitted the "?" in "messageOut?".

image.png

The most important addition though: all modules that can change an output flag now can change multiple flags at the same time. If the module has been brought to DML flags, it automatically supports this new ability. The remaining modules will get it when with their DML flag update. 

image.png

Although small by themselves, in all these changes reflect a significant improvement for mission designers, as they increase usability , decrease the number of attributes you need to set, and lessen frustration when debugging input and output flags. 

Details:

Documentation
    - Zonal Count Down - update, race condition
    - FAQ
    - General Updates
    
Modules (DML / Watchflag / significant Upgrades)
    - cfxZones 2.7.0
    - unitZone 1.1.0
    - groupTracker 1.1.0
    - cloneZone 1.4.1
    - raiseFlag 1.2.1
    - delayFlag 1.2.1 
    - reconMode 1.5.0 
    - messenger 1.2.1
    - NDB 1.2.0
    - objectDestructDetector 1.2.0 
    
Demos (updates)
    - ADF and NDB Fun
    - Object Destruct Detection
    - The Zonal Count Down 
    - Watchflags Demo 
    
Others
    - dcsCommon 

 

Cheers,

-ch

 


Edited by cfrag
  • Like 1
Link to comment
Share on other sites

8 hours ago, cfrag said:

This appears to be a knock-on effect from one of the recent changes in DCS, where units that are 'cooking off' are now exchanged for static objects and are removed from the group. As a result, when the group is wiped, those static objects aren't removed: they never belonged to the group and DML doesn't know about them. 

Disappointing to say the least. Hopefully there will be a work-around soon. 

If the change is here to stay, would it be possible to have a module that wipes a trigger zone of all objects?

This way it could work like this: spawn clones -> when all are dead run this "wipe all" module -> when it's done run the delayTimer -> when it's done trigger a new spawn event.

I'm thinking of having it be separate because if static objects are not tracked then it's "dangerous" to wipe them as part of the cloneZone everytime, so it might make sense to have it have to be invoked intentionally.

OS: Win11 Pro 64bit MB: ASUS B550-I STRIX CPU: AMD R7 5800X GPU: Nvidia GeForce RTX 2060 Super 8GB RAM: 32GB DDR4 SSD (OS and Sims): Samsung 980 Pro 2TB Accessories: TrackIR5, Warthog HOTAS, CH Pedals

Link to comment
Share on other sites

2 hours ago, Fabri91 said:

would it be possible to have a module that wipes a trigger zone of all objects?

I'll look into it - it may be a costly invocation (I'm thinking world.search() right now), but if it only happens once every few minutes it should work. May accidentally wipe other scenery, but I'll see what that turns up. You could probably safely wipe when the cloner signals empty!. Maybe run a delayFlag for a couple of seconds for better visual effect.

You probably can stack the "wiper" on top of the clone zone. But let's not get ahead of ourselves 🙂

 


Edited by cfrag
Link to comment
Share on other sites

First, thank you for your hard work and dedication to this project, it has helped me really engage with the Mission Editor. I have been working with cloner and more specifically incorporating the re-stock SAM site from the CloneZ.miz. I cannot for life of me enable the re-stocker for SAM sites in my mission or even in the mission example you provided. I made sure to delete the paused attribute; however, it does not work for me. Any advice for getting this feature to work would be extremely helpful.

Link to comment
Share on other sites

1 hour ago, Apothecary said:

I cannot for life of me enable the re-stocker for SAM sites in my mission or even in the mission example you provided

There's a good likelihood that the reason for that is that I screwed up somewhere, so let's try and build this up from the ground 🙂

Below please find a basic self-respawning (endless) cloner. The mission was build as follows

  • Created new mission
  • Added the minimum modules dcsCommon, cfxZones, cfxMX and cloneZone to ON START trigger
  • Added Observer (Su-25T), a blue APC, and a red Infantry with orders Weapons Hold

If you run the mission, the blue APC kills the red infantry. Some hours later you run out of fuel, that's it.

Now let's add a self-triggering endless spawner:

  • Place a trigger zone over the infantry, make its radius 10m or smaller, so that it only contains the red infantry
  • Add the "cloner" attribute. This attaches the cloner module to this zone
  • Add the  "onStart" = yes attribute. This (deprecated, but I am lazy) attribute will cause the cloner to undergo a single clone cycle at the start of the mission, ensuring that the infantry unit is there to be shot at
  • Add the 'clone?' = "*goClone" input. This causes the cloner to start a new cloning cycle whenever there is a change on the local "goClone" flag. Why do we use a local flag? so we can copy paste this endless cloner willy nilly over any group, and it will instantly work without changes. 
  • Here's the feedback loop: add the 'empty!' output signal, and wire it into the local "*goClone" signal. 

image.png

Now each time the last unit of the cloned group dies, empty! sends a signal on local *goClone, which feeds into the cloner's own clone? input and triggers a new cloning cycle

If you can get the above to work for you, let's see how we can expand this to cover your requirements.

endless respawn demo.miz


Edited by cfrag
Link to comment
Share on other sites

19 hours ago, Fabri91 said:

would it be possible to have a module that wipes a trigger zone of all objects?

It's actually less complex than I had feared (interesting, but non-vital information: the new static objects a name based on the unit object they replace). I've added a new 'wiper' module that can do that. In the PoC Mission (added below), I simply add a "wipe?" attribute and the trigger flag to the zone, and when that flag is banged, all static units inside the zone are removed. I'll flesh this out a bit more, to be able to have more fine-grained control over what is being deleted (you may even be able to delete some scenery, will have to check) and to turn this into a general-purpose module, but the basic functionality is there. In the example below, the cloner's empty! triggers the wipe.

image.png

So if you want it now in your mission, copy the following script, and add it as a DOSCRIPT to your start trigger (just like any other module). Any zone that has a 'wipe?' attribute will then delete all static objects inside when the flag is pulled.

 Hope this helps

-ch

wiper = {}
wiper.version = "0.0.0d"
wiper.verbose = false 
wiper.ups = 1 
wiper.requiredLibs = {
	"dcsCommon", -- always
	"cfxZones", -- Zones, of course 
}
wiper.wipers = {}
--[[--
	Version History
	1.0.0 - Initial Version 

--]]--
function wiper.addWiper(theZone)
	table.insert(wiper.wipers, theZone)
end

function wiper.getWiperByName(aName) 
	for idx, aZone in pairs(wiper.wipers) do 
		if aName == aZone.name then return aZone end 
	end
	if wiper.verbose then 
		trigger.action.outText("+++wpr: no wiper with name <" .. aName ..">", 30)
	end 
	
	return nil 
end

--
-- read zone 
-- 
function wiper.createWiperWithZone(theZone)
	theZone.triggerWiperFlag = cfxZones.getStringFromZoneProperty(theZone, "wipe?", "*<none>")
	
	-- triggerWiperMethod
	theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
	if cfxZones.hasProperty(theZone, "triggerWiperMethod") then 
		theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerWiperMethod", "change")
	end 
	
	if theZone.triggerWiperFlag then 
		theZone.lastTriggerWiperValue = cfxZones.getFlagValue(theZone.triggerWiperFlag, theZone)
	end

	
	if wiper.verbose then 
		trigger.action.outText("+++wpr: new wiper zone <".. theZone.name ..">", 30)
	end
end

--
-- Wiper main action
--
function wiper.objectHandler(theObject, theCollector)
	--trigger.action.outText("theObject = <" .. theObject:getName() ..">", 30)
	table.insert(theCollector, theObject)
	return true 
end

function wiper.isTriggered(theZone)
	--trigger.action.outText("Enter isTriggered for " .. theZone.name, 30)
	-- get current location in case theZone is moving 
	local p = cfxZones.getPoint(theZone)
	local lp = {x = p.x, y = p.z}
	p.y = land.getHeight(lp)
	local collector = {}
	
	-- now build the search argument 
	local args = {
			id = world.VolumeType.SPHERE,
				params = {
					point = p,
					radius = theZone.radius
				}
			}
	-- set up remaining arguments
	local cat = Object.Category.STATIC
	
	-- now call search
	world.searchObjects(cat, args, wiper.objectHandler, collector)

	-- wipe'em!
	for idx, anObject in pairs(collector) do
		anObject:destroy()
	end
end

--
-- Update 
--
function wiper.update()
	-- call me in a second to poll triggers
	timer.scheduleFunction(wiper.update, {}, timer.getTime() + 1/wiper.ups)
		
	for idx, aZone in pairs(wiper.wipers) do
		
		if cfxZones.testZoneFlag(aZone, aZone.triggerWiperFlag, aZone.triggerWiperMethod, "lastTriggerWiperValue") then 
			if wiper.verbose then 
					trigger.action.outText("+++wpr: triggered on ".. aZone.wiperFlag " for <".. aZone.name ..">", 30)
				end
			wiper.isTriggered(aZone)
		end 
		
	end
end


--
-- Config & Start
--
function wiper.readConfigZone()
	local theZone = cfxZones.getZoneByName("wiperConfig") 
	if not theZone then 
		if wiper.verbose then 
			trigger.action.outText("+++wpr: NO config zone!", 30)
		end 
		theZone = cfxZones.createSimpleZone("wiperConfig") -- temp only
	end 
	
	wiper.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
	
	wiper.ups = cfxZones.getNumberFromZoneProperty(theZone, "ups", 1)
		
	if wiper.verbose then 
		trigger.action.outText("+++wpr: read config", 30)
	end 
end

function wiper.start()
	-- lib check
	if not dcsCommon.libCheck then 
		trigger.action.outText("cfx Wiper requires dcsCommon", 30)
		return false 
	end 
	if not dcsCommon.libCheck("cfx Wiper", wiper.requiredLibs) then
		return false 
	end
	
	-- read config 
	wiper.readConfigZone()
	
	-- process cloner Zones 
	local attrZones = cfxZones.getZonesWithAttributeNamed("wipe?")
	for k, aZone in pairs(attrZones) do 
		wiper.createWiperWithZone(aZone) -- process attributes
		wiper.addWiper(aZone) -- add to list
	end
	
	-- start update 
	wiper.update()
	
	trigger.action.outText("cfx Wiper v" .. wiper.version .. " started.", 30)
	return true 
end

-- let's go!
if not wiper.start() then 
	trigger.action.outText("cfx Wiper aborted: missing libraries", 30)
	wiper = nil 
end

 

viper w uu.miz


Edited by cfrag
  • Like 1
Link to comment
Share on other sites

Thanks for the amazingly quick reply! 😄

I'll test it out some and report back any issues.

EDIT:

I tried your example and it seemed to work, but upon changing the units (Tigr on red side with an Abrams on the blue side) the wreckage still appears to stick around - have attached some screenshots in addition to the modified mission file. Especially in the first one you can clearly see both the old and new vehicle.

Screen_220401_215301_resized.jpg

Screen_220401_215317_resized.jpg

Screen_220401_215321_resized.jpg

viper w uu mod.miz


Edited by Fabri91
Added test report

OS: Win11 Pro 64bit MB: ASUS B550-I STRIX CPU: AMD R7 5800X GPU: Nvidia GeForce RTX 2060 Super 8GB RAM: 32GB DDR4 SSD (OS and Sims): Samsung 980 Pro 2TB Accessories: TrackIR5, Warthog HOTAS, CH Pedals

Link to comment
Share on other sites

cfrag

 

Thanks, I tested it out and it's working fine by me. My overall goal with the script is to have the SAM sites around the bluefor base, reset and rearm after every couple 5 to 10 minutes.

Also, does the wiper work on the spawner module? 

 

Thanks!


Edited by Apothecary
Link to comment
Share on other sites

5 hours ago, Apothecary said:

Also, does the wiper work on the spawner module? 

Yes - the idea of DML is that it works like Lego Bricks - you take a few, and they work in concert.  If they don't this would be the place to complain 🙂

 

12 hours ago, Fabri91 said:

the wreckage still appears to stick around - have attached some screenshots in addition to the modified mission file

Thanks! That should help to find out what's going on.

Link to comment
Share on other sites

13 hours ago, Fabri91 said:

the wreckage still appears to stick around

Initially I thought that simply enabling 'preWipe' for the cloner would do the trick, but it does not. I then added some code that examines the contents of the zone for any objects that are present, list them, then remove them. In the image below you can see that the modules sees a clean plate, but there are still flames and debris.

It appears that debris and fire/smoke are not part of the world DB, and aren't accessible to the mission. They'll vanish on their own timer.

This means that (for the time being) neither flames, smoke nor wreckage can be removed, this may require ED update their engine (perhaps add an 'effect' category in addition to the 6 that we already have?) before this becomes prossible

image.png


Edited by cfrag
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...