| 06-29-2009, 04:14 PM | #1 | |
I finished my first complete tower that I coded myself, and I'd like if I could get some critiques on it please. Here is a description of how the tower works: You upgrade the generic elemental tower into a Generator tower. The generator tower has a "Build Link Tower" ability which you use to construct a link tower (based upon the build mini-structure item ability). There is a limited range in which you can construct the link tower, which is displayed by a blue ring of special effects (the ring is only shown when the generator tower is selected). Once you construct the link tower, a lightning effect link is established and any ground enemy unit that touches it gets damaged. If your builder touches the lightning, then he gets slowed for a short duration. After a cooldown, you can destroy and rebuild the link tower in a different location if you wish. This tower is designed so that each player can only have ONE at a time, so I realize that it's not MUI to have multiple copies of the tower per player, but it doesn't need to be for the purposes of my map. Also, the generator can only build one link tower at a time, and must destroy the old link tower before you can build a new one. This code uses Ammorth's LineSegment library and Vexorian's SimError. Some globals that are used (that are not part of the code) are: 1. BuilderChosen (which is an array that contain's every player's builder) 2. Generator tower ids (GENERATOR_TOWER_ID, GENERATOR_2_TOWER_ID, GENERATOR_3_TOWER_ID) 3. SELL_ID and DEMOLISH_ID (abilities for selling and demolishing towers) 4. ENUM_GROUP is an empty global group that is used, but never filled. 5. PlayerArea is an array that contains the player's entire playing area rect. This is to prevent the range circle thing from appearing outside of the player's area. Generator main code: JASS://Generator Tower by Zaraf scope GeneratorTower initializer Init //Uses Ammorth's LineSegment and Vexorian's SimError globals private constant string CIRCLE_SFX = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl" //Special effect that the range circle is made up of private constant string UNIT_SFX_HIT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" //Special effect randomly shown when a unit touched the electricity. private constant integer PASSIVE_ID = 'A00Q' //raw code of the passive dummy ability that is meant to keep track of the ability levels, and display information about the tower to players. private constant integer LINK_ABILITY = 'A03O' //raw code of the link ability. private constant integer DESTROY_LINK = 'A046' //raw code of the destroy ability that destroys the links. private constant integer DUMMY_SPELL = 'A016' //raw code of the dummy spell for slowing the builder private constant integer DAZE_DUMMY_ID = 'h03V' //raw code of the dummy unit that casts the slow spell private constant attacktype A_TYPE = ATTACK_TYPE_CHAOS // Attack type of damage dealt by electricity to creeps. private constant damagetype D_TYPE = DAMAGE_TYPE_UNIVERSAL // Damage type of damage dealt by electricity to creeps. private constant weapontype W_TYPE = WEAPON_TYPE_WHOKNOWS // Weapon type of damage dealt by electricity to creeps. private constant real EFFECT_HEIGHT = 100.00 //The height above ground that the lightning effect appears. private constant string EFFECT_TYPE = "FORK" //The code of the type of lightning effect that appears. private constant real TIMER_PERIOD = 2.00 //The speed at which the color of the lightning changes. private constant real DAMAGE_PERIOD = 0.10 //The speed at which the lightning is checked to see if units are nearby and to damage them. private constant string MESSAGE1 = "\nCannot build the Link Tower outside of range." //error message that appears private constant string MESSAGE2 = "\nCannot build Link Tower too close to the Generator Tower." //error message that appears private constant real MIN_DISTANCE = 128.00 //Minimum distance at which you cannot build a link tower private constant real ANGLE_INCREMENT = 10.0 //Make sure this is divisible into 360 WITHOUT a remainder endglobals //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private struct Generator unit u //the generator tower unit c //the link tower unit d //slow casting dummy unit player p //owner of generator integer id //player id of owner integer lvl //level of the base generator ability integer cc = 1 //color counter, keeps track of the color array slot to use real xu //x position of generator real yu //y position of generator real xc //x position of link tower real yc //y position of link tower effect array circ [100] //Array used to create and destroy the range circle lightning e //lightning effect that is created boolean bh = false //Builder Hit - checks if the builder has been dazed boolean cool = false //DestroyLinkCoolDown - checks if the cooldown is happening or not boolean link = false //LinkActive - checks if the link is established or not endstruct globals private Generator array GeneratorStruct private integer FilterPlayerId //The variable used to feed the player id to the filter function private boolexpr DamageFilter private string array LightningSFX endglobals //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function Range takes integer lvl returns real return 300.0 + (150.0 * lvl) endfunction private function Damage takes integer lvl returns real return 0.0 + (1.0 * lvl) endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function Cond takes nothing returns boolean local boolean a = GetOwningPlayer(GetTriggerUnit()) == GetTriggerPlayer() local boolean b = GetUnitTypeId(GetTriggerUnit()) == GENERATOR_TOWER_ID local boolean c = GetUnitTypeId(GetTriggerUnit()) == GENERATOR_2_TOWER_ID local boolean d = GetUnitTypeId(GetTriggerUnit()) == GENERATOR_3_TOWER_ID return a and (b or c or d) endfunction private function UpgradeCondition takes nothing returns boolean return (GetUnitLevel(BuilderChosen[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))+1]) >= 30) endfunction private function LinkTowerCond takes nothing returns boolean return GetSpellAbilityId() == LINK_ABILITY endfunction private function LinkTowerCheck takes nothing returns boolean return GetUnitTypeId(GetConstructedStructure()) == GENERATOR_LINK_TOWER_ID endfunction private function DestroyLinkCheck takes nothing returns boolean return (GetSpellAbilityId() == DESTROY_LINK) or (GetSpellAbilityId() == SELL_ID) or (GetSpellAbilityId() == DEMOLISH_ID) endfunction private function FilterTargets takes unit filter returns boolean return IsUnitType(filter,UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(filter) > 0.406) and IsUnitType(filter,UNIT_TYPE_FLYING) == false endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function DamageFilterActions takes nothing returns boolean //Actions performed in the GroupEnumUnitsInRangeOfSegment(...) local Generator g = GeneratorStruct[FilterPlayerId] local integer n = GetRandomInt(0,100) if FilterTargets(GetFilterUnit()) then if IsUnitInRangeOfSegment(GetFilterUnit(), g.xu, g.yu, g.xc, g.yc, 40.0) == true then //40.0 is a closely measured distance to use for the width of the electricity. if GetFilterUnit() == BuilderChosen[g.id+1] then //If your builder touches the electricity, he gets slowed. if g.bh == false then set g.bh = true set g.d = CreateUnit(Player(11), DAZE_DUMMY_ID, g.xu, g.yu, 0) call UnitApplyTimedLife(g.d, 'BTLF', 1.) call UnitAddAbility(g.d, DUMMY_SPELL) call SetUnitAbilityLevel(g.d, DUMMY_SPELL, g.lvl) call IssueTargetOrder(g.d, "slow", GetFilterUnit()) //slow the builder if he touches the electricity call DestroyEffect(AddSpecialEffectTarget(UNIT_SFX_HIT, GetFilterUnit(), "chest")) //Create special effect on builder endif else call UnitDamageTarget(g.u, GetFilterUnit(), Damage(g.lvl), false, false, A_TYPE, D_TYPE, W_TYPE) if n > 90 then //There is a 10% chance of showing the special effect on the enemy unit. call DestroyEffect(AddSpecialEffectTarget(UNIT_SFX_HIT, GetFilterUnit(), "chest")) endif endif endif endif return false endfunction private function GeneratorDamage takes nothing returns nothing //Runs the code to detect and damage units touching the electricity. local Generator g = Generator(GetTimerData(GetExpiredTimer())) set FilterPlayerId = g.id call GroupEnumUnitsInRangeOfSegment(ENUM_GROUP, g.xu, g.yu, g.xc, g.yc, 1.0, DamageFilter) //Range of 1.0 used because it just seems to work properly. Any higher creates a range that is too large. if g.link == false then call ReleaseTimer(GetExpiredTimer()) endif endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function ChangeLightningColor takes nothing returns nothing //Timer function that changes the color of the electricity local Generator g = Generator(GetTimerData(GetExpiredTimer())) local integer i = g.cc local integer n = GetRandomInt(1,100) if g.link == false then call ReleaseTimer(GetExpiredTimer()) else if n > 95 then set n = GetRandomInt(0,2) call DestroyEffect(AddSpecialEffect(LightningSFX[n], GetUnitX(g.u), GetUnitY(g.u))) call DestroyEffect(AddSpecialEffect(LightningSFX[n], GetUnitX(g.c), GetUnitY(g.c))) endif call SetLightningColor(g.e, RedColor[g.cc], GreenColor[g.cc], BlueColor[g.cc], 1.0) if g.cc == 51 then set g.cc = 1 else set g.cc = g.cc + 1 endif set g.bh = false endif endfunction private function CreateLink takes Generator g returns nothing //Creates the electrical link when you build a link tower. local timer t = NewTimer() local timer damagetimer = NewTimer() local integer n = GetRandomInt(0,2) local real zu local real zc set g.xu = GetUnitX(g.u) set g.yu = GetUnitY(g.u) set g.xc = GetUnitX(g.c) set g.yc = GetUnitY(g.c) set zu = GetPointZ(g.xu, g.yu) + EFFECT_HEIGHT set zc = GetPointZ(g.xc, g.yc) + EFFECT_HEIGHT call DestroyEffect(AddSpecialEffect(LightningSFX[n], g.xu, g.yu)) call DestroyEffect(AddSpecialEffect(LightningSFX[n], g.xc, g.yc)) set g.e = AddLightningEx(EFFECT_TYPE, false, g.xu, g.yu, zu, g.xc, g.yc, zc) call SetLightningColor(g.e, 1.0, 0.0, 0.0, 1.0) set g.link = true call SetTimerData(t, g) call TimerStart(t, TIMER_PERIOD, true, function ChangeLightningColor) call SetTimerData(damagetimer, g) call TimerStart(damagetimer, DAMAGE_PERIOD, true, function GeneratorDamage) set t = null set damagetimer = null endfunction private function BreakLink takes Generator g returns nothing //Destroys the link set g.link = false call DestroyLightning(g.e) call KillUnit(g.c) endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function SelectActions takes Generator g returns nothing //These actions happen when you select the tower. It creates the blue range ring around the tower. local integer n = 0 local rect r = PlayerArea[POS[g.id+1]] local real x local real y local real offset = 50.0 local real angle = 0.0 loop exitwhen n > (360.0/ANGLE_INCREMENT) if g.circ[n] != null then call DestroyEffect(g.circ[n]) set g.circ[n] = null endif set x = g.xu + Range(g.lvl) * Cos( (angle + ANGLE_INCREMENT * n) * bj_DEGTORAD) set y = g.yu + Range(g.lvl) * Sin( (angle + ANGLE_INCREMENT * n) * bj_DEGTORAD) if x <= GetRectMinX(r) then set x = GetRectMinX(r) + offset endif if x >= GetRectMaxX(r) then set x = GetRectMaxX(r) - offset endif if y <= GetRectMinY(r) then set y = GetRectMinY(r) + offset endif if y >= GetRectMaxY(r) then set y = GetRectMaxY(r) - offset endif set g.circ[n] = AddSpecialEffect(CIRCLE_SFX, x, y) set n = n + 1 endloop endfunction private function SelectEvent takes nothing returns nothing local Generator g = GeneratorStruct[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] call SelectActions(g) endfunction private function DeselectActions takes Generator g returns nothing //These actions happen when you deselect the tower. It destroys the range ring around the tower. local integer n = 0 loop exitwhen n > (360.0/ANGLE_INCREMENT) call DestroyEffect(g.circ[n]) set g.circ[n] = null set n = n + 1 endloop endfunction private function DeselectEvent takes nothing returns nothing local Generator g = GeneratorStruct[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] call DeselectActions(g) endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function LinkTowerBuild takes nothing returns nothing //This is the ability to build the link tower local Generator g = GeneratorStruct[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] local location trgt = GetSpellTargetLoc() local real tx = GetLocationX(trgt) local real ty = GetLocationY(trgt) local real dx = tx - g.xu local real dy = ty - g.yu local real Dist = SquareRoot(dx * dx + dy * dy) local rect r = PlayerArea[POS[g.id+1]] if tx <= GetRectMinX(r) or tx >= GetRectMaxX(r) or ty <= GetRectMinY(r) or ty >= GetRectMaxY(r) then call SetUnitPosition(g.u, g.xu, g.yu) //This is meant to stop the tower's ability from working...cancelling the link tower creation ability. call SimError(g.p, MESSAGE1) elseif Dist > Range(g.lvl) then call SetUnitPosition(g.u, g.xu, g.yu) //This is meant to stop the tower's ability from working...cancelling the link tower creation ability. call SimError(g.p, MESSAGE1) elseif Dist < MIN_DISTANCE then call SetUnitPosition(g.u, g.xu, g.yu) //This is meant to stop the tower's ability from working...cancelling the link tower creation ability. call SimError(g.p, MESSAGE2) endif call RemoveLocation(trgt) set trgt = null endfunction private function LinkTowerConstruction takes nothing returns nothing //This is the detection of the actual finished construction of the link tower local Generator g = GeneratorStruct[GetPlayerId(GetOwningPlayer(GetConstructedStructure()))] set g.c = GetConstructedStructure() set g.xu = GetUnitX(g.c) set g.yu = GetUnitY(g.c) set g.cool = true //This is set to true so that the first time the generator uses the destroy link ability, that it does nothing. call UnitAddAbility(g.u, DESTROY_LINK) call SetUnitAbilityLevel(g.u, DESTROY_LINK, g.lvl) call UnitRemoveAbility(g.u, LINK_ABILITY) call IssueImmediateOrder(g.u, "tranquility") //This orders the Generator to use the Destroy Link ability so that it starts the cooldown. call CreateLink(g) endfunction private function DestroyLinkCast takes nothing returns nothing //This runs when you try to sell/demolish the tower or destroy the link tower. local Generator g = GeneratorStruct[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] if ( (GetSpellAbilityId() == SELL_ID) or (GetSpellAbilityId() == DEMOLISH_ID) ) and (g.lvl > 0) then call DeselectActions(g) call BreakLink(g) call SellActions() call g.destroy() elseif g.cool == false then //Prevents the destroying of link tower when the destroy ability is first used to start the cooldown. call BreakLink(g) call UnitAddAbility(g.u, LINK_ABILITY) call SetUnitAbilityLevel(g.u, LINK_ABILITY, g.lvl) call UnitRemoveAbility(g.u, DESTROY_LINK) else set g.cool = false //if the cooldown has not started yet, then start it without destroying the link tower. endif endfunction private function GeneratorUpgrade takes nothing returns nothing //This runs when you upgrade the generator local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit())) local integer i = GetUnitTypeId(GetTriggerUnit()) local Generator g if (i == GENERATOR_TOWER_ID) then //Initial upgrading of the tower (the tower is upgrade from a generic elemental tower rather than directly built) set GeneratorStruct[id] = Generator.create() set g = GeneratorStruct[id] set g.u = GetTriggerUnit() set g.p = GetOwningPlayer(g.u) set g.id = GetPlayerId(g.p) set g.lvl = GetUnitAbilityLevel(g.u, PASSIVE_ID) set g.xu = GetUnitX(g.u) set g.yu = GetUnitY(g.u) call SelectActions(g) elseif (i == GENERATOR_2_TOWER_ID) or (i == GENERATOR_3_TOWER_ID) then //Upgrades to the generator tower set g = GeneratorStruct[id] call IncUnitAbilityLevel(GetTriggerUnit(), PASSIVE_ID) set g.lvl = GetUnitAbilityLevel(GetTriggerUnit(), PASSIVE_ID) call SelectActions(g) call DestroyLinkCast() endif endfunction //*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ private function Init takes nothing returns nothing local integer n = 0 local trigger t1 = CreateTrigger() local trigger t2 = CreateTrigger() local trigger t3 = CreateTrigger() local trigger t4 = CreateTrigger() local trigger t5 = CreateTrigger() local trigger t6 = CreateTrigger() loop exitwhen n > 7 call TriggerRegisterPlayerUnitEvent(t1, Player(n), EVENT_PLAYER_UNIT_SELECTED, null) call TriggerRegisterPlayerUnitEvent(t2, Player(n), EVENT_PLAYER_UNIT_DESELECTED, null) call TriggerRegisterPlayerUnitEvent(t3, Player(n), EVENT_PLAYER_UNIT_SPELL_CAST, null) call TriggerRegisterPlayerUnitEvent(t4, Player(n), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null) call TriggerRegisterPlayerUnitEvent(t5, Player(n), EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, null) call TriggerRegisterPlayerUnitEvent(t6, Player(n), EVENT_PLAYER_UNIT_SPELL_CAST, null) set n = n + 1 endloop call TriggerAddCondition(t1, Condition(function Cond)) call TriggerAddCondition(t2, Condition(function Cond)) call TriggerAddCondition(t3, Condition(function LinkTowerCond)) call TriggerAddCondition(t4, Condition(function UpgradeCondition)) call TriggerAddCondition(t5, Condition(function LinkTowerCheck)) call TriggerAddCondition(t6, Condition(function DestroyLinkCheck)) call TriggerAddAction(t1, function SelectEvent) call TriggerAddAction(t2, function DeselectEvent) call TriggerAddAction(t3, function LinkTowerBuild) call TriggerAddAction(t4, function GeneratorUpgrade) call TriggerAddAction(t5, function LinkTowerConstruction) call TriggerAddAction(t6, function DestroyLinkCast) set DamageFilter = Condition(function DamageFilterActions) set LightningSFX[0] = "Abilities\\Spells\\Demon\\DemonBoltImpact\\DemonBoltImpact.mdl" set LightningSFX[1] = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl" set LightningSFX[2] = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" endfunction endscope Color Init: (this is where the RedColor, GreenColor and BlueColor arrays are initialized) JASS:library ColorInit initializer Init globals real array RedColor real array GreenColor real array BlueColor endglobals private function Init takes nothing returns nothing set RedColor[1] = 1.0 set RedColor[2] = 1.0 set RedColor[3] = 1.0 set RedColor[4] = 1.0 set RedColor[5] = 1.0 set RedColor[6] = 1.0 set RedColor[7] = 1.0 set RedColor[8] = 1.0 set RedColor[9] = 1.0 set RedColor[10] = 1.0 set RedColor[11] = 1.0 set RedColor[12] = 0.9 set RedColor[13] = 0.8 set RedColor[14] = 0.7 set RedColor[15] = 0.6 set RedColor[16] = 0.5 set RedColor[17] = 0.4 set RedColor[18] = 0.3 set RedColor[19] = 0.2 set RedColor[20] = 0.1 set RedColor[21] = 0.0 set RedColor[22] = 0.0 set RedColor[23] = 0.0 set RedColor[24] = 0.0 set RedColor[25] = 0.0 set RedColor[26] = 0.0 set RedColor[27] = 0.0 set RedColor[28] = 0.0 set RedColor[29] = 0.0 set RedColor[30] = 0.0 set RedColor[31] = 0.0 set RedColor[32] = 0.0 set RedColor[33] = 0.0 set RedColor[34] = 0.0 set RedColor[35] = 0.0 set RedColor[36] = 0.0 set RedColor[37] = 0.5 set RedColor[38] = 0.6 set RedColor[39] = 0.7 set RedColor[40] = 0.8 set RedColor[41] = 0.9 set RedColor[42] = 1.0 set RedColor[43] = 1.0 set RedColor[44] = 1.0 set RedColor[45] = 1.0 set RedColor[46] = 1.0 set RedColor[47] = 1.0 set RedColor[48] = 1.0 set RedColor[49] = 1.0 set RedColor[50] = 1.0 set RedColor[51] = 1.0 set GreenColor[1] = 0.0 set GreenColor[2] = 0.1 set GreenColor[3] = 0.2 set GreenColor[4] = 0.3 set GreenColor[5] = 0.4 set GreenColor[6] = 0.5 set GreenColor[7] = 0.6 set GreenColor[8] = 0.7 set GreenColor[9] = 0.8 set GreenColor[10] = 0.9 set GreenColor[11] = 1.0 set GreenColor[12] = 1.0 set GreenColor[13] = 1.0 set GreenColor[14] = 1.0 set GreenColor[15] = 1.0 set GreenColor[16] = 1.0 set GreenColor[17] = 1.0 set GreenColor[18] = 1.0 set GreenColor[19] = 1.0 set GreenColor[20] = 1.0 set GreenColor[21] = 1.0 set GreenColor[22] = 1.0 set GreenColor[23] = 1.0 set GreenColor[24] = 1.0 set GreenColor[25] = 1.0 set GreenColor[26] = 1.0 set GreenColor[27] = 1.0 set GreenColor[28] = 1.0 set GreenColor[29] = 1.0 set GreenColor[30] = 1.0 set GreenColor[31] = 1.0 set GreenColor[32] = 0.9 set GreenColor[33] = 0.8 set GreenColor[34] = 0.7 set GreenColor[35] = 0.6 set GreenColor[36] = 0.5 set GreenColor[37] = 0.0 set GreenColor[38] = 0.0 set GreenColor[39] = 0.0 set GreenColor[40] = 0.0 set GreenColor[41] = 0.0 set GreenColor[42] = 0.0 set GreenColor[43] = 0.0 set GreenColor[44] = 0.0 set GreenColor[45] = 0.0 set GreenColor[46] = 0.0 set GreenColor[47] = 0.0 set GreenColor[48] = 0.0 set GreenColor[49] = 0.0 set GreenColor[50] = 0.0 set GreenColor[51] = 0.0 set BlueColor[1] = 0.0 set BlueColor[2] = 0.0 set BlueColor[3] = 0.0 set BlueColor[4] = 0.0 set BlueColor[5] = 0.0 set BlueColor[6] = 0.0 set BlueColor[7] = 0.0 set BlueColor[8] = 0.0 set BlueColor[9] = 0.0 set BlueColor[10] = 0.0 set BlueColor[11] = 0.0 set BlueColor[12] = 0.0 set BlueColor[13] = 0.0 set BlueColor[14] = 0.0 set BlueColor[15] = 0.0 set BlueColor[16] = 0.0 set BlueColor[17] = 0.0 set BlueColor[18] = 0.0 set BlueColor[19] = 0.0 set BlueColor[20] = 0.0 set BlueColor[21] = 0.0 set BlueColor[22] = 0.1 set BlueColor[23] = 0.2 set BlueColor[24] = 0.3 set BlueColor[25] = 0.4 set BlueColor[26] = 0.5 set BlueColor[27] = 0.6 set BlueColor[28] = 0.7 set BlueColor[29] = 0.8 set BlueColor[30] = 0.9 set BlueColor[31] = 1.0 set BlueColor[32] = 1.0 set BlueColor[33] = 1.0 set BlueColor[34] = 1.0 set BlueColor[35] = 1.0 set BlueColor[36] = 1.0 set BlueColor[37] = 1.0 set BlueColor[38] = 1.0 set BlueColor[39] = 1.0 set BlueColor[40] = 1.0 set BlueColor[41] = 1.0 set BlueColor[42] = 1.0 set BlueColor[43] = 0.9 set BlueColor[44] = 0.8 set BlueColor[45] = 0.7 set BlueColor[46] = 0.6 set BlueColor[47] = 0.5 set BlueColor[48] = 0.4 set BlueColor[49] = 0.3 set BlueColor[50] = 0.2 set BlueColor[51] = 0.1 endfunction endlibrary Here is a screenshot of the tower in action: Please keep in mind that I'm new to vJASS coding, and so I'm asking for this critique to help improve my coding. If you would like to try the tower out, please let me know and I'll send you the map and show you how to test the tower. I can't attach the map here since this is part of the rest of my map. Thanks for any help! EDIT: Whoops forgot to add in description of tower. Thanks Anitarf. |
| 06-29-2009, 05:12 PM | #2 |
I really don't understand how you aren't able to make a MUI code in vJass. Also, what is the tower supposed to do, I don't see any explanation of it. |
| 06-29-2009, 05:29 PM | #3 |
Whoops forgot to add in a tower description. Now added, thanks! As for the MUI, it's not that I can't make it MUI for multiple towers per player, but it's that my map doesn't require it. Every player is limited to constructing only ONE of this tower at a time (if they sell it, they can build it again). It is not possible for a player to have 2 generator towers at the same time. So then why complicate the code further to add a functionality that would never be used? If I ever did decide to allow more than one (which I don't expect I ever will), then I could go back and modify it accordingly. However, I do believe that this code is MPI. So that each player can have a single generator without any problems. Please don't make an issue out of "You should make it MUI even if you don't need it!" Thanks. |
| 06-29-2009, 06:13 PM | #4 | |
Quote:
Summary A "It's more efficient to program for MUI." Z "But I don't need it, so how is that more efficient?" A "It will save you time in the future if you decide you want to reuse the code." Z "Then I can just go back and modify it." A "But it's good practice for a good programming habit." Z "I don't need it and I'd like to avoid confusing structs." |
| 06-29-2009, 06:13 PM | #5 |
well, if you like it, and if you like how it looks(which i think is cool btw), and if there are no bugs, i don't really feel like reading all of your code, its just long. however, tell me if you'd like feedback on specific parts of the code... that would be a bit more detailed then. also, there exists a tag called [ hiddenjass] and [ /hiddenjass], that one looks better. edit: oh yeah, detailed and good first post btw, explaining a bit more about the internal workings of your code would definitely be helpful though. |
| 06-29-2009, 06:49 PM | #6 | |
Quote:
I expect there should be a more efficient approach to handling the colors, Z. Have you considered using a formula instead of such unwieldy arrays? |
| 06-29-2009, 07:11 PM | #7 | |
Quote:
Yeah, but wasn't sure what kind of a formula to use. Despite being an engineer, I suck at creating formulas ;) Probably cause I'm a chemical engineer and I'm better at making dangerous chemcials than I am at mathematical formulas ;) But these are the steps in the way the color changes with regards to RGB. The numbers refer to percentages. R 100 = Red 100%, G 0 to 100 = Green incrementing from 0% to 100%, B 0 = Blue 0% The increments I used were 10% increases each time. step 1 (starting): (R 100) (G 0) (B 0) step 2: (R 100) (G 0 to 100) (B 0) step 3: (R 100 to 0) (G 100) (B 0) step 4: (R 0) (G 100) (B 0 to 100) step 5: (R 0) (G 100 to 0) (B 100) step 6: (R 0 to 100) (G 0) (B 100) step 7: (R 100) (G 0) (B 100 to 0) and then you're back to step 1. However, there is one difference in my array. I've eliminated some of the color steps. Mainly on step 5, instead of Green going from 100% to 0%, I have it go from 100% to 50%, and Red also has a sudden jump to 50% and increases to 100% (instead of 0% to 100%). The reason for this is that this range of color looks very bad for the lightning effect I used. It becomes syncronized with the lightning's default colors, and just looks like fat blue lightning effects. So I just cut those out, and when the lightning starts turning blue, it reaches a point where it just jumps to a purple. This was another reason I thought to avoid a formula since I would have to account for this exception. I realize this might be a bit confusing to understand, but I hope it was clear enough :) |
| 06-29-2009, 07:22 PM | #8 | |
Quote:
|
| 06-29-2009, 08:01 PM | #9 | |
Quote:
Not really the case with this tower. Since it's quite specialized. The things that could be generalized have already been established (LineSegment). My lightning color thing and the range thing are things which I might want to add to other towers, but the way they are right now, they by themselves are already MUI if I were to put them on other towers. |
