• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Trigger] Reduce build time

Status
Not open for further replies.
Level 5
Joined
Nov 21, 2014
Messages
151
As the title reads, is it possible that after a certain event (with a condition) there will be an action that targets a building that reduces it's remaining build time? Let's say building B takes 30 seconds to build, it has 15 seconds left, and I use for instance, an ability that reduces the build time by 10 seconds, such reducing it to 5 seconds. Is this possible? Thanks in advance as always :goblin_good_job::goblin_good_job:
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,184
There is no way to detect build time with triggers. But let's say that you check the object editor for that information, then there is an action to set construction progress to X%.

Then there's the second problem, you can't detect the current construction progress. You have to detect when a building is being built, then use a counter in a loop to keep track of that.

I might want to create a system for this sometime in the future, because it might actually be useful.
 
Level 5
Joined
Nov 21, 2014
Messages
151
There is no way to detect build time with triggers. But let's say that you check the object editor for that information, then there is an action to set construction progress to X%.

Then there's the second problem, you can't detect the current construction progress. You have to detect when a building is being built, then use a counter in a loop to keep track of that.

I might want to create a system for this sometime in the future, because it might actually be useful.

Yeah I know, I wasn't able to figure it out so I asked here so maybe someone knows something about this, and about that system:
Don't feel pushed about that, because that is so totally awesome, and if you do decide to make it, I would love to use it :). :grin::thumbs_up:
 
Level 5
Joined
Nov 21, 2014
Messages
151
I can give you a non MUI example, making it MUI is a boring process :p

If I show you how to do it can you make it MUI yourself?

I think that if I say that I have no clue what MUI is you know what the answer to that question is lol..:grin::grin:
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,184
random tutorial said:
MUI is Multi-Unit-Instanceability.It means that if 2 or more units cause a trigger to fire (casting a spell would be best example), the spell's effect will work properly for both units that cast the ability. if the trigger wasent MUI the spell would only work for 1 of the units Also, MUI is basicly impossible to achieve with waits.

Basically, if something MUI it can be used by any number of units at the same time.

This is achieved with either arrays or a hashtable in GUI.

edit: whatever. I did it.
Disclaimer: I know the timer is never turned off.
JASS:
//! zinc
	library BuildTime
	{
		hashtable hash;
		group g;
		public function RegisterBuildings()
		{
			integer i = 0;
			integer h;
			while(i < udg_total)
			{
				SaveReal(hash, udg_building[i], 0, udg_time[i]);
				i += 1;
			}
		}
		
		function Time2Percent(real time, real maxTime) -> integer
		{
			return R2I((time / maxTime) * 100);
		}
		
		public function ReduceConstructionTime(unit u, real seconds)
		{
			integer h = GetHandleId(u);
			real time = LoadReal(hash, h, 1);
			real maxTime = LoadReal(hash, GetUnitTypeId(u), 0);
			integer cPercent = Time2Percent(time, maxTime);
			integer nPercent = Time2Percent(seconds, maxTime);
			UnitSetConstructionProgress(u, cPercent + nPercent);
			BJDebugMsg(GetUnitName(u) + " construction progress increased by " + R2S(cPercent + nPercent) + "%" + "(" + R2S(seconds) + ")");
		}
		
		function gActions()
		{
			unit u = GetEnumUnit();
			integer h = GetHandleId(u);
			real counter = LoadReal(hash, h, 1) + 1;
			BJDebugMsg(R2S(counter));
			SaveReal(hash, h, 1, counter);
			u = null;
		}
		
		function onPeriodic()
		{
			ForGroup(g,  function gActions);
		}
		
		function onConstruction()
		{
			GroupAddUnit(g, GetTriggerUnit());
			BJDebugMsg(GetUnitName(GetTriggerUnit()));
		}
		
		function onConstructionFinish()
		{
			unit u = GetTriggerUnit();
			GroupRemoveUnit(g, u);
			FlushChildHashtable(hash, GetHandleId(u));
			u = null;
		}
		
		function onInit()
		{
			trigger t = CreateTrigger();
			trigger t2 = CreateTrigger();
			hash = InitHashtable();
			g = CreateGroup();
			TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH);
			TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_START);
			TriggerAddAction(t, function onConstruction);
			TriggerAddAction(t2, function onConstructionFinish);
			TimerStart(CreateTimer(), 1, true, function onPeriodic);
			t = null;
			t2 = null;
		}
	}
//! endzinc
  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set building[0] = Barracks
      • Set time[0] = 60.00
      • Set building[1] = Lumber Mill
      • Set time[1] = 60.00
      • Set building[2] = Blacksmith
      • Set time[2] = 70.00
      • Set building[3] = Scout Tower
      • Set time[3] = 25.00
      • Set total = 4
      • Custom script: call RegisterBuildings()
  • demo
    • Events
      • Unit - A unit Begins construction
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Barracks
    • Actions
      • Wait 0.00 seconds
      • Custom script: call ReduceConstructionTime(GetTriggerUnit(), 30)
The demo trigger reduce barrack construction time by 30 seconds which is equal to 50%
 
Last edited:
Level 5
Joined
Nov 21, 2014
Messages
151
Basically, if something MUI it can be used by any number of units at the same time.

This is achieved with either arrays or a hashtable in GUI.

edit: whatever. I did it.
Disclaimer: I know the timer is never turned off.
JASS:
//! zinc
	library BuildTime
	{
		hashtable hash;
		group g;
		public function RegisterBuildings()
		{
			integer i = 0;
			integer h;
			while(i < udg_total)
			{
				SaveReal(hash, udg_building[i], 0, udg_time[i]);
				i += 1;
			}
		}
		
		function Time2Percent(real time, real maxTime) -> integer
		{
			return R2I((time / maxTime) * 100);
		}
		
		public function ReduceConstructionTime(unit u, real seconds)
		{
			integer h = GetHandleId(u);
			real time = LoadReal(hash, h, 1);
			real maxTime = LoadReal(hash, GetUnitTypeId(u), 0);
			integer cPercent = Time2Percent(time, maxTime);
			integer nPercent = Time2Percent(seconds, maxTime);
			UnitSetConstructionProgress(u, cPercent + nPercent);
			BJDebugMsg(GetUnitName(u) + " construction progress increased by " + R2S(cPercent + nPercent) + "%" + "(" + R2S(seconds) + ")");
		}
		
		function gActions()
		{
			unit u = GetEnumUnit();
			integer h = GetHandleId(u);
			real counter = LoadReal(hash, h, 1) + 1;
			BJDebugMsg(R2S(counter));
			SaveReal(hash, h, 1, counter);
			u = null;
		}
		
		function onPeriodic()
		{
			ForGroup(g,  function gActions);
		}
		
		function onConstruction()
		{
			GroupAddUnit(g, GetTriggerUnit());
			BJDebugMsg(GetUnitName(GetTriggerUnit()));
		}
		
		function onConstructionFinish()
		{
			unit u = GetTriggerUnit();
			GroupRemoveUnit(g, u);
			FlushChildHashtable(hash, GetHandleId(u));
			u = null;
		}
		
		function onInit()
		{
			trigger t = CreateTrigger();
			trigger t2 = CreateTrigger();
			hash = InitHashtable();
			g = CreateGroup();
			TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH);
			TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_START);
			TriggerAddAction(t, function onConstruction);
			TriggerAddAction(t2, function onConstructionFinish);
			TimerStart(CreateTimer(), 1, true, function onPeriodic);
			t = null;
			t2 = null;
		}
	}
//! endzinc
  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set building[0] = Barracks
      • Set time[0] = 60.00
      • Set building[1] = Lumber Mill
      • Set time[1] = 60.00
      • Set building[2] = Blacksmith
      • Set time[2] = 70.00
      • Set building[3] = Scout Tower
      • Set time[3] = 25.00
      • Set total = 4
      • Custom script: call RegisterBuildings()
  • demo
    • Events
      • Unit - A unit Begins construction
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Barracks
    • Actions
      • Wait 0.00 seconds
      • Custom script: call ReduceConstructionTime(GetTriggerUnit(), 30)
The demo trigger reduce barrack construction time by 30 seconds which is equal to 50%

Do I just copy the trigger to a custom text trigger and it will work? ( I don't really work with custom text so I don't know if it imports variables or not, if not, can you please post them if they are used, thanks :grin: )
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,184
Yes. Make a trigger, convert it to custom text. Replace the text with my text, and then use the same GUI triggers as me.

You need to use the exact same variable names, or it will give errors.
Also you need JNGP, which is a bit of a downside I suppose. But pretty much everyone does anyway.
Here is a test map.

edit: also worked a bit to fix some issues. So I uploaded it.
http://www.hiveworkshop.com/forums/spells-569/reducebuildtime-277284/
 

Attachments

  • test.w3x
    18.1 KB · Views: 42
Last edited:
Status
Not open for further replies.
Top