• 🏆 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!

[JASS] Interactive abilities with allied units based on Aall

Status
Not open for further replies.
Level 26
Joined
Feb 2, 2006
Messages
1,695
Based on the ability 'Aall' I want to provide abilities from NPC units which allow interaction with the NPCs.
I think that the same is used in Gaias ORPG to activate quests. I've added an 'Aall' based ability to the NPC and a channel based ability called "Talk to the NPC".
When I am getting near the NPC which is owned by an allied player I am able to cast the ability after selecting the NPC.
Unfortunately I cannot detect the ordering player with GetTriggerPlayer(). It does always return the NPC's owner. Is there any way to achieve this?

The greate benefit would be that I do not have to give may character more abilities for interaction but can use the abilities of the NPCs. From discussions with other mappers I got the suggestion to use a unit per player or something like this as workaround.

Any idea what would be the best way to achieve what I want?
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
I would recommend checking "smart" order on the target (right click)
Then you know when the player right clicked on that unit.
Then you order the given unit to cast "interact" (a custom ability based on channel that isnt visible) and when that ability is cast, you interact with the NPC.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
My initial approach was to react on the smart ability but then one would have to order right click und on that NPC and it led to confusion. Some players usually just click on the NPC. GetBuyingUnit() always returns null for me somehow so I just used GetOwningPlayer(GetSoldUnit()). I do remove the sold unit immediately but the stock does not refresh. In fact the unit can only bought one time although I set the interval to 0. Did I miss something. Maybe I will use a tome instead. What would be the benefit of that? That I do not have to remove it manually I guess.
 
I recommend using dummy units. They are the easiest to handle and don't cause any unwanted behaviour with inventory systems.
If you give them 1 health and negative health regen, such as "does not revive, does not decay" property, you don't even have to bother removing them manually.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
Sry to bring this up again and thx Zwiebelchen I will try this.

It is still not working the way it should.
If I remove the sold unit with:
JASS:
call RemoveUnit(GetSoldUnit())
using the event EVENT_UNIT_SELL the unit is removed but also removed from the shop. Is this a bug or am I doing something wrong?

Besides GetBuyingUnit() returns null so I can only check if the character is in range but not if the character is the buying unit.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
JASS:
private static method triggerConditionSell takes nothing returns boolean
			local thistype this = thistype(DmdfHashTable.global().handleInteger(GetTriggeringTrigger(), "this"))
			
			if (GetSellingUnit() == this.unit() and GetUnitTypeId(GetSoldUnit()) == 'n05E') then
				return true
			endif
			
			return false
		endmethod
		
		private static method triggerActionSell takes nothing returns nothing
			local thistype this = thistype(DmdfHashTable.global().handleInteger(GetTriggeringTrigger(), "this"))
			
			debug call Print("Selling unit: " + GetUnitName(GetSellingUnit()))
			debug call Print("Buying unit " + GetUnitName(GetBuyingUnit()))
				
			//if (ACharacter.isUnitCharacter(GetBuyingUnit())) then
			if (GetPlayerController(GetOwningPlayer(GetSoldUnit())) == MAP_CONTROL_USER and ACharacter.playerCharacter(GetOwningPlayer(GetSoldUnit())) != 0 and IsUnitInRange(ACharacter.playerCharacter(GetOwningPlayer(GetSoldUnit())).unit(), this.unit(), 600.0)) then
				call this.openForCharacter(ACharacter.playerCharacter(GetOwningPlayer(GetSoldUnit())))
			endif
			
			//call SetUnitInvulnerable(GetSoldUnit(), true)
			//call PauseUnit(GetSoldUnit(), true)
			//call TriggerSleepAction(0.0)
			//call RemoveUnit(GetSoldUnit())
		endmethod

...

set this.m_sellTrigger = CreateTrigger()
			call TriggerRegisterUnitEvent(this.m_sellTrigger, whichUnit, EVENT_UNIT_SELL)
			call TriggerAddCondition(this.m_sellTrigger, Condition(function thistype.triggerConditionSell))
			call TriggerAddAction(this.m_sellTrigger, function thistype.triggerActionSell)
call DmdfHashTable.global().setHandleInteger(this.m_sellTrigger, "this", this)
Apparently the removal from the stock was not because of the removal of the bought unit. If I do not remove the bought unit the unit is still removed from the stock. Btw. the stock is NOT a building. It is a unit.
 
Level 26
Joined
Feb 2, 2006
Messages
1,695
Ok as expected
JASS:
call this.openForCharacter(...)
caused the problem. It called PauseUnit(...) and after unpausing, no unit was available in the stock anymore.
I fixed it by using TriggerSleepAction(0.0) before calling openForCharacter() although a 0 timer might be better.

BUT GetBuyingUnit() does still return null!!!
 
Last edited:
Status
Not open for further replies.
Top