| 04-09-2006, 06:37 AM | #1 |
JASS:function Equator_Shot_S23 takes string x returns string local integer i = StringLength(x) //Makes String Length = 3 by adding 0s to the start if (i == 0) then return "000" elseif (i == 1) then return "00" + x elseif (i == 2) then return "0" + x //ERROR ON THIS LINE else return x endif return "000" //dummy return for compile reasons endfunction Getting "Missing endfunction error"... don't understand why. |
| 04-09-2006, 06:58 AM | #2 |
I just copied and pasted your code. No errors here. Your error is within another function missing "endfunction" at the end. Sometimes it'll highlight the wrong area. |
| 04-09-2006, 07:56 AM | #3 |
if everyone used PJASS, this forum would die |
| 04-09-2006, 04:44 PM | #4 | |
Quote:
However, I've gone through all of my code line by line and can't find a missing endfunction. I'm really tempted to just post all my code and ask if you guys can find the error but there's 500 lines of code and I'd rather track it down myself so I know for future reference what caused it. Any other ideas as to what can cause this error to be reported? Also, if it matters, it reports every line after that in my code to be outside a function... EDIT: Well I've looked through everything and I can't find the error, so here is my code (I realize there are probably a lot of other mistakes/missing code to make the spell do what I want since this is my first time using CS, feel free to point those out if you want, but my main focus is this specific problem atm): JASS:// ************************************************************************* // * Spell: Equator Shot 1.0 * // * * // * Requirements: 1.) Create dummy ability in WE that does nothing * // * but target a unit, called Equator Shot. * // * (Or Copy the ability from this map) * // * 2.) Vexorian's Caster System * // * (See Map custom script code) * // * * // * Description: Creates a number of orbs in a radius around the * // * unit. the distance of each individual orb is * // * random. The orbs then fly/home-in on the target * // * unit. As each orb impacts the target unit, * // * a new, bigger orb appears over the target's head. * // * The size of the new big orb is determined by the * // * total distance traveled by each sub orb. * // * Once all orbs impact the target unit, damage is * // * dealt based on the size of the new, big orb. * // * It does pretty color effects. I hope. ;) * // * * // * Leveling Up: Increasing levels of the spell modifies these * // * spell elements: * // * A. Possible Distance from target unit the orbs * // * can be created. * // * - By design, this increases the size of the * // * larger orb. Which increases Damage. * // * * // * * // * Modifiable (Listed respectively to functions below * // * Components: * // * 1. Number of mini orbs. * // * 2. Model used for mini orbs. * // * 3. Model used for big orb. * // * 4. If you use default rainbow colors, or #5 & #6 * // * 5. Color of the mini orbs. * // * 6. Color of the large orb. * // * 7. Height at which the orbs fly to the unit. * // * 8. Possible Distance Increment per level. * // * 9. Minimum Distance for mini-orb creation. * // * 10. % of distance traveled dealt in Damage (per-orb)* // * 11. Spell AbilityId * // * 12. Movespeed of Mini-orbs * // * 13. Scale of mini-orbs * // * 14. Collision Size of mini-orbs * // * 15. Max Size the Big Orb can reach * // * 16. The height above the unit the Big Orb hovers * // * * // * Other spell elements could probably be changed to * // * your liking with relative ease. * // * * // * Credits: The excellent resources at wc3campaigns.net * // * Inspired by Blade.dk's Boulder Roll spell, * // * and the DOTA spells "Illuminate" & "Impetus" * // * ...and Captain Planet. There, I said it. * // * * // * Created by mmx2000 (Battle.net handle: TheGodRinner) * // * * // * Version History: * // * * // * 1.0 - ...created it ;) * // * * // ************************************************************************* //=========================================================================== //======== MODIFIABLE ELEMENTS ============================================== //=========================================================================== function Equator_Shot_NumberOfShots takes nothing returns integer return 8 //the number of bolts flying in from map edges. endfunction function Equator_Shot_MiniOrbModel takes nothing returns string return "units\nightelf\Wisp\Wisp" //Model File for mini-orbs endfunction function Equator_Shot_BigOrbModel takes nothing returns string return "units\nightelf\Wisp\Wisp" //Model File for Big Orb endfunction function Equator_Shot_DefaultColorSystem takes nothing returns boolean return true //If you want to use the default scheme where each orb is a different //color, and the big orb's color is a function of the mini-orb's colors //combining. //Set this to false if you want all mini-orbs the same color and want to set //the color of the big orb. //If you leave this as true, ignore the next 2 functions endfunction function Equator_Shot_MiniOrbColor takes nothing returns string //Only used if not DefaultColorSystem return "000255000100" //1st 3 digits = red value 0-255 //2nd 3 digits = green value 0-255 //3rd 3 digits = blue value 0-255 //4th 3 digits = Alpha Value, 0-100 //You -must- use 3 digits for each slot. IE:, '10' = '010' endfunction function Equator_Shot_BigOrbColor takes nothing returns string //Only used if not DefaultColorSystem return "000255000100" //Same format above, RGB endfunction function Equator_Shot_FlyingHeight takes nothing returns real return GetRandomReal( 20.00 , 100.00 ) //The flying height boundaries of projectiles //Note: doesn't have to be random... I just did that to make it more interesting :) endfunction function Equator_Shot_DistancePerLevel takes nothing returns real return 300.0 //The maximum distance a mini-orb can be created from the target unit. //The further away, the more damage done. //For each level of the spell, the orbs can be created at // (this #) * (spell lvl) distance. endfunction function Equator_Shot_MinimumDistance takes nothing returns real return 50.0 //Minimum distance from target unit for mini-orb creation endfunction function Equator_Shot_PercentDamage takes nothing returns real return 10.0 //The percent of the distance dealt in damage //IE: in the default settings of the spell, //at Level 4, with 8 mini-orbs, at a distance interval of 300, //there is the potential for 9600 units of distance to be traveled. //Or, the minimum distance traveled, 50*8 = 400. //So the damage will range between 40 - 960. //As you can see, by varying the distances and percents, you can effectively //control the damage range similar to dice rolls. endfunction function Equator_Shot_SpellAbilityId takes nothing returns integer return 'A000' //AbilityId endfunction function Equator_Shot_MoveSpeed takes nothing returns real return 522.0 //Movement speed of the mini-orbs. I believe 522 is max game speed. endfunction function Equator_Shot_MiniOrbScale takes nothing returns real return 0.5 //Scale of the MiniOrb Model endfunction function Equator_Shot_CollisionSize takes nothing returns real return 20.0 endfunction function Equator_Shot_BigOrbMaxScale takes nothing returns real return 5.0 //The maximum size the Big Orb can expand to, in reference to the original model's scale endfunction function Equator_Shot_BigOrbAddHeight takes nothing returns real return 50.0 //Big Orb's creation height = Targeted Unit's flying height + this value endfunction //=========================================================================================== //======== UTILITY FUNCTIONS ================================================================ //=========================================================================================== function Equator_Shot_Null takes nothing returns nothing //does nothing endfunction function Equator_Shot_RoundR2I takes real x returns integer //Rounds a real number to the nearest integer. //Purpose? Since the JASS native R2I just truncates the decimal places off a number, //JASS essentially always rounds down when converting. This allows for traditional math //methods of rounding. //.0->.499999999 = round down //.5->1.0 = round up local integer y = R2I(x) local real z = RAbsBJ(x - I2R(y)) if ((z >= 0.0) and (z < .5)) then return y else return y+1 endif return 0 //dummy return for compile reasons endfunction function Equator_Shot_S23 takes string x returns string local integer i = StringLength(x) //Makes String Length = 3 by adding 0s to the start if (i == 0) then return "000" elseif (i == 1) then return "00" + x elseif (i == 2) then return "0" + x else return x endif return "000" //dummy return for compile reasons endfunction function Equator_Shot_RainbowColor takes integer OrbNumber returns string //This function is a little hard to understand. Essentially, it is creating a gradient //from Red->Orange->Yellow->Green->Teal->Blue->Purple->Red //It works based on the fact that colors in WC3 are RGB; because of this, as you go //along this gradient, at 100% color saturation (no black/white), you are only changing //2 of the R, G, or B values (the 3rd is 0.) //Thinking about this, there are only 5 combinations of 2 colors: // 1.) Red = 255, Green 0->255, Blue = 0 // 2.) Red = 255->0, Green = 255, Blue = 0 // 3.) Red = 0, Green = 255, Blue = 0->255 // 4.) Red = 0, Green = 255->0, Blue = 255 // 5.) Red = 0->255, Green = 0, Blue = 255 // //To keep things a little simple, I use integer math to estimate where on the gradient scale //the color should be. // //OrbNumber = the "number" orb you are firing. IE: The 3rd orb. // //returns: string in the format "RRRGGGBBB100" Note: The 100 corresponds to Orb Alpha Value. //Determine how many orbs go in each gradient local integer NumberOfShots = Equator_Shot_NumberOfShots() local integer NumberInEachCombo = NumberOfShots / 5 local integer increment = 255 / NumberInEachCombo //how much the R,G,orB value changes local string tempstring //Determine which gradient combination this orb is in. local integer Combo = Equator_Shot_RoundR2I( OrbNumber / NumberOrShots * 5 ) //Set color set increment = (increment * i) - increment if (Combo == 1) then //Red = 255, Green 0->255, Blue = 0 set tempstring = Equator_Shot_S23(I2S(increment)) return "255" + tempstring + "000100" elseif (Combo == 2) then //Red = 255->0, Green = 255, Blue = 0 set tempstring = Equator_Shot_S23(I2S(255 - increment)) return tempstring + "255000100" elseif (Combo == 3) then //Red = 0, Green = 255, Blue = 0->255 set tempstring = Equator_Shot_S23(I2S(increment)) return "000255" + tempstring + "100" elseif (Combo == 4) then //Red = 0, Green = 255->0, Blue = 255 set tempstring = Equator_Shot_S23(I23(255 - increment)) return "000" + tempstring + "255100" else //Red = 0->255, Green = 0, Blue = 255 set tempstring = Equator_Shot_S23(I2S(255 - increment)) return tempstring + "000255100" endif return "000000000000" //dummy return for compile reasons endfunction function Equator_Shot_CreateBigOrb takes unit TargetUnit, unit CastingUnit returns unit //Initially (with default color system) colorless and alpha=0% //Reason: As mini-orbs impact it, it gains some of the pigment //of that mini-orb, and becomes more visible. //TargetUnit = Unit to create the orb over local unittype BigOrbModel = Equator_Shot_BigOrbModel() local integer BigOrbRed local integer BigOrbGreen local integer BigOrbBlue local integer BigOrbAlpha local string BigOrbColorString local unit BigOrb //Create Effect set BigOrb = CollisionMissile_CreateLoc(BigOrbModel, GetUnitLoc(TargetUnit), 0, 522, 200, 10000, GetUnitFlyHeight(TargetUnit) + Equator_Shot_BigOrbAddHeight(), false, 0, function Equator_Shot_Null()) call CollisionMissile_SetTarget(BigOrb, TargetUnit) //Tell the missile to target the TargetUnit //Set Orb Color: if (Equator_Shot_DefaultColorSystem() == false) then set BigOrbColorString = Equator_Shot_BigOrbColor() else set BigOrbColorString = "000000000000" endif set BigOrbRed = S2I(SubString(BigOrbColorString, 1, 3)) set BigOrbGreen = S2I(SubString(BigOrbColorString, 4, 6)) set BigOrbBlue = S2I(SubString(BigOrbColorString, 7, 9)) set BigOrbAlpha = S2I(SubString(BigOrbColorString, 10, 12)) call SetUnitVertexColor(BigOrb, BigOrbRed, BigOrbGreen, BigOrbBlue, BigOrbAlpha) //Initialize BigOrb to have the count of mini-orbs that have impacted it = 0 & attach data call AttachInt(BigOrb, "NumberOfHits", 0) call AttachString(BigOrb, "BigOrbColorString", BigOrbColorString) call AttachReal(BigOrb, "BigOrbScale", 1.0) call AttachInt(BigOrb, "Damage", 0) call AttachObject(BigOrb, "TargetUnit", TargetUnit) call AttachObject(BigOrb, "CastingUnit", CastingUnit) return BigOrb endfunction function Equator_Shot_ModifyBigOrb takes unit BigOrb, string MiniOrbColorString, real AddScale, integer OrbDamage returns nothing //BigOrb = The BigOrb //MiniOrbColorString = "RRRGGGBBBAAA" //AddScale = The increase to the BigOrb's Scale local integer MiniOrbRed local integer MiniOrbGreen local integer MiniOrbBlue local integer BigOrbRed local integer BigOrbGreen local integer BigOrbBlue local string BigOrbColorString = GetAttachedString(BigOrb, "BigOrbColorString") local real BigOrbScale = GetAttachedReal(BigOrb, "BigOrbScale") + AddScale local integer NumberOfHits = GetAttachedInt(BigOrb, "NumberOfHits") + 1 local integer Damage = GetAttachedInt(BigOrb, "Damage") + OrbDamage //Save # of hits / damage call AttachInt(BigOrb, "NumberOfHits", NumberOfHits) call AttachInt(BigOrb, "Damage", Damage) //Increase Scale call SetUnitScalePercent(BigOrb, BigOrbScale, BigOrbScale, BigOrbScale) call AttachReal(BigOrb, "BigOrbScale", BigOrbScale) //Adjust color if (Equator_Shot_DefaultColorSystem == false) then set BigOrbColorString = Equator_Shot_BigOrbColorString() endif set MiniOrbRed = S2I(SubString(MiniOrbColorString, 1, 3)) set MiniOrbGreen = S2I(SubString(MiniOrbColorString, 4, 6)) set MiniOrbBlue = S2I(SubString(MiniOrbColorString, 7, 9)) set MiniOrbAlpha = S2I(SubString(MiniOrbColorString, 10, 12)) set BigOrbRed = S2I(SubString(BigOrbColorString, 1, 3)) + MiniOrbRed * AddScale set BigOrbGreen = S2I(SubString(BigOrbColorString, 4, 6)) + MiniOrbGreen * AddScale set BigOrbBlue = S2I(SubString(BigOrbColorString, 7, 9)) + MiniOrbBlue * AddScale set BigOrbAlpha = S2I(SubString(BigOrbColorString, 10, 12)) + MiniOrbAlpha * AddScale call AttachString(BigOrb, "BigOrbColorString", BigOrbRed+BigOrbGreen+BigOrbBlue+BigOrbAlpha) if (NumberOfHits == Equator_Shot_NumberOfShots()) then call Equator_Shot_DamageUnit(GetAttachedObject(BigOrb, "CastingUnit"), GetAttachedObject(BigOrb, "TargetUnit"), Damage) call CollisionMissile_Destroy(BigOrb) endif endfunction function Equator_Shot_DamageUnit takes unit CastingUnit, unit TargetUnit, integer Damage returns nothing call DamageUnitByTypes(CastingUnit, TargetUnit, Damage, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC) endfunction //******************************************* //* This trigger is a continuation of the * //* TRIGGER ACTIONS code. This is necessary * //* for the detection of Orbs hitting the * //* target. * //******************************************* function Equator_Shot_OrbHit takes nothing returns nothing //When a CollisionMissile hits the target local unit MiniOrb = GetTriggerCollisionMissile() local unit TargetUnit = GetAttachedObject(MiniOrb, "TargetUnit") local player CastingPlayer = GetAttachedObject(MiniOrb, "CastingPlayer") local unit CastingUnit = GetAttachedObject(MiniOrb, "CastingUnit") local location OrbStart = GetAttachedObject(MiniOrb, "loc") local unit BigOrb = GetAttachedObject(MiniOrb, "BigOrb") local string MiniOrbColorString = GetAttachedString(MiniOrb, "MiniOrbColorString") local location OrbEnd = GetUnitLoc(TargetUnit) local integer OrbDamage //The damage this single orb contributes local real DamageFactor //Percent of total possible damage this orb represents local integer PossibleDamage //Total Possible Damage for all missiles combined local integer NumberOfShots = Equator_Shot_NumberOfShots() local integer DistancePerLevel = Equator_Shot_DistancePerLevel() local integer PercentDamage = Equator_Shot_PercentDamage() / 100 local integer SpellLevel = GetUnitAbilityLevel(CastingUnit, Equator_Shot_SpellAbilityId()) local real DistanceTraveled = DistanceBetweenPoints(OrbStart, OrbEnd) //Make sure the unit hit = target unit if(GetTriggerUnit() == TargetUnit) then //Calculate modification to BigOrb's Scale //Assumption: At 100% possible damage for the level, the Big Orb expands to 100% of Max Big Orb Scale //Calculate DamageFactor: set PossibleDamage = NumberOfShots * SpellLevel * DistancePerLevel * PercentDamage set OrbDamage = Distance * PercentDamage set DamageFactor = OrbDamage / PossibleDamage call Equator_Shot_ModifyBigOrb(BigOrb, MiniOrbColorString, DamageFactor, OrbDamage) call CollisionMissile_Destroy(MiniOrb) endif call RemoveLocation(OrbStart) call RemoveLocation(OrbEnd) endfunction //=========================================================================================== //======== TRIGGER CONDITIONS =============================================================== //=========================================================================================== function Trig_Equator_Shot_Conditions takes nothing returns boolean //Check that the ability being cast is == Equator_Shot if ( not ( GetSpellAbilityId() == Equator_Shot_SpellAbilityId() ) ) then return false endif return true endfunction //=========================================================================================== //======== TRIGGER ACTIONS ================================================================== //=========================================================================================== function Trig_Equator_Shot_Actions takes nothing returns nothing //Variable Declarations local integer NumberOfShots = Equator_Shot_NumberOfShots() local string MiniOrbModel = Equator_Shot_MiniOrbModel() local boolean DefaultColors = Equator_Shot_DefaultColorSystem() local string MiniOrbColorString local real FlyingHeight //'Set' later local real DistancePerLevel = Equator_Shot_DistancePerLevel() local real MinimumDistance = Equator_Shot_MinimumDistance() local real PercentDamage = Equator_Shot_PercentDamage() local integer SpellAbilityId = Equator_Shot_SpellAbilityId() local real MoveSpeed = Equator_Shot_MoveSpeed() local real MiniOrbScale = Equator_Shot_MiniOrbScale() local real CollisionSize = Equator_Shot_CollisionSize() local real Angle = (360.0 / NumberOfShots) local unit CastingUnit = GetSpellAbilityUnit() local player CastingPlayer = GetOwningPlayer(CastingUnit) local unit TargetUnit = GetSpellTargetUnit() local integer i //loop counter local real tempdistance local unit MiniOrb local location temploc local integer MiniOrbRed local integer MiniOrbGreen local integer MiniOrbBlue local integer MiniOrbAlpha local unit BigOrb = Equator_Shot_CreateBigOrb(TargetUnit, CastingUnit) //Create the MiniOrbs. set i = 1 loop exitwhen (i > NumberOfShots) //Get a distance value for the orb. set tempdistance = GetRandomReal(MinimumDistance, DistancePerLevel * GetUnitAbilityLevel(CastingUnit, SpellAbilityId) ) //Calculate it's location set temploc = PolarProjectionBJ(GetUnitLoc(TargetUnit), tempdistance, Angle * i) //Create the orb set MiniOrb = CollisionMissile_CreateLoc(MiniOrbModel, temploc, ((Angle * i) + 180), MoveSpeed, 200, 2000, Equator_Shot_FlyingHeight(), false, CollisionSize, function Equator_Shot_OrbHit()) call CollisionMissile_SetTarget(MiniOrb, TargetUnit) //Tell the missile to target the TargetUnit call RemoveLocation(temploc) call SetUnitScale(MiniOrb, MiniOrbScale, MiniOrbScale, MiniOrbScale) //Set Orb Color: if (DefaultColors == true) then set MiniOrbColorString = Equator_Shot_RainbowColor(i) else set MiniOrbColorString = Equator_Shot_MiniOrbColor() endif set MiniOrbRed = S2I(SubString(MiniOrbColorString, 1, 3)) set MiniOrbGreen = S2I(SubString(MiniOrbColorString, 4, 6)) set MiniOrbBlue = S2I(SubString(MiniOrbColorString, 7, 9)) set MiniOrbAlpha = S2I(SubString(MiniOrbColorString, 10, 12)) call SetUnitVertexColor(MiniOrb, MiniOrbRed, MiniOrbGreen, MiniOrbBlue, MiniOrbAlpha) //Attach Information to Orb call AttachInt(MiniOrb, "OrbNumber", i) call AttachReal(MiniOrb, "loc", GetUnitLoc(MiniOrb)) call AttachObject(MiniOrb, "CastingPlayer", CastingPlayer) call AttachObject(MiniOrb, "TargetUnit", TargetUnit) call AttachObject(MiniOrb, "CastingUnit", CastingUnit) call AttachObject(MiniOrb, "BigOrb", BigOrb) call AttachObject(MiniOrb, "MiniOrbColorString", MiniOrbColorString) //increment loop set i = i + 1 endloop //Everything else now happens in function Equator_Shot_OrbHit endfunction //=========================================================================== function InitTrig_Equator_Shot takes nothing returns nothing set gg_trg_Equator_Shot = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Equator_Shot, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Equator_Shot, Condition( function Trig_Equator_Shot_Conditions) ) call TriggerAddAction( gg_trg_Equator_Shot, function Trig_Equator_Shot_Actions ) endfunction |
| 04-09-2006, 07:57 PM | #5 |
A single slash denotes a special character. \\ is the way to put a single slash into a string. It took about 20s to find that with PJASS, btw. Although the error message was not the clearest: "Non valid escape sequences in string". "units\nightelf\Wisp\Wisp" -> "units\\nightelf\\Wisp\\Wisp" along with all the other model strings. a couple other things: Equator_Shot_DefaultColorSystem -> Equator_Shot_DefaultColorSystem() function Equator_Shot_OrbHit() -> function Equator_Shot_OrbHit |
| 04-09-2006, 08:19 PM | #6 |
Actually JassCraft uses PJASS as syntax check. |
| 04-09-2006, 08:32 PM | #7 | |
Quote:
Yeah. And, thanks a bunch. I knew there were a lot of other errors (syntax & logic)... didn't want to fix the logic errors until I got this tracked down, and syntax I couldn't check cause the parser would sort of crash in jasscraft with this error. Thanks a ton! :D rep+!!! |
