• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] On Local Player and IsUnitSelected

Status
Not open for further replies.
Hello,

I've made this system which repairs a player's character when they select a repair structure (on some conditions). It works correctly for all players in single player mode, but in multiplayer it does not (It doesn't seem to desync though, so that's nice)

Here's the script:

JASS:
scope Repair initializer i
	globals
		private constant real MAX_DISTANCE = 400.
		private constant real REPAIR_TIMEOUT = 30.
		private constant real FRAC = 1./2.
		private constant string TOO_OFTEN_ERROR = "You can't heal yourself again so soon!"
		private constant string MAX_HEALTH_ERROR = "Your ship is already at maximum health!"
		private constant string DISTANCE_ERROR = "Your ship is too far away!"
		private constant string ALLIANCE_ERROR = "You can't use the opposition's Repair Port!"
		private constant string HEAL_MODEL = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
		private real array lastRepair[12]
	endglobals
	
	private function c takes nothing returns boolean
		local player p
		local unit tU=GetTriggerUnit()
		local integer id
		local real max
		local real life
		local integer index=0
		if not Game_ended then
			loop
				exitwhen index>11
				if IsUnitSelected(tU,Game_players[index]) then
					set id=index
					exitwhen true
				endif
				set index=index+1
			endloop
			set p = Player(id)
			if Game_localPlayer==p then
				call SelectUnit(tU,false)
				call SelectUnit(Ships_ships[id],true)
			endif
			if IsUnitAlly(tU,p) then
				if IsUnitInRange(tU,Ships_ships[id],MAX_DISTANCE) then
					set life = GetWidgetLife(Ships_ships[id])
					set max = GetUnitState(Ships_ships[id],UNIT_STATE_MAX_LIFE)
					if life<max then
						if Game_seconds - lastRepair[id] > REPAIR_TIMEOUT then
							set lastRepair[id] = Game_seconds
							call SetWidgetLife(Ships_ships[id],life + (max-life)*FRAC)
							call DestroyEffect(AddSpecialEffectTarget(HEAL_MODEL,Ships_ships[id],"origin"))
						else
							call SimError(p,TOO_OFTEN_ERROR)
						endif
					else
						call SimError(p,MAX_HEALTH_ERROR)
					endif
				else
					call SimError(p,DISTANCE_ERROR)
				endif
			else
				call SimError(p,ALLIANCE_ERROR)
			endif
		endif
		set tU=null
		return false
	endfunction
	
	private function i takes nothing returns nothing
		local trigger t = CreateTrigger()
		local integer index=0
		loop
			exitwhen index>11
			set lastRepair[index] = -1.*REPAIR_TIMEOUT
			set index=index+1
		endloop
		call TriggerRegisterUnitEvent(t,Game_westRepair,EVENT_UNIT_SELECTED)
		call TriggerRegisterUnitEvent(t,Game_eastRepair,EVENT_UNIT_SELECTED)
		call TriggerAddCondition(t,Condition(function c))
		set t=null
	endfunction
endscope

I would appreciate any suggestions or advice.

Edit: To be clear, "Doesn't work" means it doesn't seem to do anything at all - selecting a repair structure doesn't even deselect it.
 
I would add a debug line at the top of function C and check if the code fires on select event at all and if so, which unit is selected. Check for Game_westRepair and Game_eastRepair.

It's just guessing because the code looks good per se. The bug could be in one of the _ variables.

Good idea and next thing would be to print the index obtained, but it's kind of a hassle to test this since I don't use jngp 2.x

How you know it works for all players in single player?

I tested it with different players.

---

I'm going to rewrite it to use EVENT_PLAYER_UNIT_SELECTED so I can access the triggering player and see if that fixes everything.
 
Status
Not open for further replies.
Top