share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua
changeset 13579 ff7378430675
parent 13449 57de4f050891
child 13580 dc4ce9f486b0
equal deleted inserted replaced
13578:145ee99575d4 13579:ff7378430675
     2 HedgewarsScriptLoad("/Scripts/Locale.lua")
     2 HedgewarsScriptLoad("/Scripts/Locale.lua")
     3 HedgewarsScriptLoad("/Scripts/Tracker.lua")
     3 HedgewarsScriptLoad("/Scripts/Tracker.lua")
     4 HedgewarsScriptLoad("/Scripts/Params.lua")
     4 HedgewarsScriptLoad("/Scripts/Params.lua")
     5 
     5 
     6 --[[
     6 --[[
     7 Space Invasion 1.2
     7 Space Invasion
     8 
     8 
     9 === DOCUMENTATION ===
     9 === DOCUMENTATION ===
    10 
    10 
    11 == SCRIPT CONFIGURATION ==
    11 == SCRIPT CONFIGURATION ==
    12 You can configure this script a little bit, you only have to edit the game scheme.
    12 You can configure this script a little bit, you only have to edit the game scheme.
    78 >>> no shield, no radar pings and only 3 barrels (could be some hard mode)
    78 >>> no shield, no radar pings and only 3 barrels (could be some hard mode)
    79 
    79 
    80 (empty string)
    80 (empty string)
    81 >>> Use defaults for everything
    81 >>> Use defaults for everything
    82 
    82 
    83 
       
    84 -- VERSION HISTORY
       
    85 ----------------
       
    86 -- version 0.1
       
    87 ----------------
       
    88 -- conversion of tumbler into space invasion
       
    89 -- a million and one changes
       
    90 -- bells and whistles
       
    91 
       
    92 ----------------
       
    93 -- version 0.2
       
    94 ----------------
       
    95 -- code slowly getting cleaner, it still looks like a spaghetti monster tho
       
    96 -- lots of console tracking :/
       
    97 -- all visual gears are now compulsary (will probably revert this)
       
    98 -- implemented fMod to try combat desyncs and bring this in line with dev
       
    99 
       
   100 ----------------
       
   101 -- version 0.3
       
   102 ----------------
       
   103 -- values of scoring changed to 3:10, and now based on vCircScore
       
   104 -- time gained from killing a red circ increased from 3 to 4
       
   105 -- circles now spawn at a distance of at least 800 or until sanity limit
       
   106 -- roundsLimit now based off MinesTime (kinda, its an experiment)
       
   107 
       
   108 -----------------
       
   109 --0.4
       
   110 -----------------
       
   111 -- commented out a lot of WriteLnToConsoles (dont need them at this point)
       
   112 -- added some different WriteLnToConsoles
       
   113 -- changed some of the collision detect for explosives in checkvarious()
       
   114 
       
   115 -----------------
       
   116 --0.5
       
   117 -----------------
       
   118 -- added implementation for a projectile shield
       
   119 -- added a "bonus" orange invader that partially recharges player shield
       
   120 -- added a tough "blueboss" blue invader
       
   121 -- expanded user feedback
       
   122 -- circles now have health and are capable of being merely "damaged"
       
   123 -- redid a lot of the collision code and added CircleDamaged
       
   124 -- added more sounds to events
       
   125 -- added more visual gears
       
   126 
       
   127 -----------------
       
   128 --0.6
       
   129 -----------------
       
   130 -- removed a few WriteLns
       
   131 -- added randomized grunts on circ damage
       
   132 -- added (mostly) graceful fading out of circles :D:
       
   133 -- changed odds for circles
       
   134 -- changed user feedback
       
   135 -- fixed the location of the explosion where player bashes into circ
       
   136 
       
   137 -----------------
       
   138 --0.7
       
   139 -----------------
       
   140 -- added PlaySound(sndSuddenDeath) when ammo gets depleted
       
   141 -- added an extra "Ammo Depleted" note if user presses fire while empty
       
   142 -- specified how much shield power is gained on shield powerup collection
       
   143 -- changed odds for circles AGAIN, ammo is now sliiightly more common
       
   144 -- switched most of the explosions/smoke effects back to non-critical vgears (with a few exceptions)
       
   145 -- tumbletime is now based off turntime and is variable
       
   146 -- delete explosives in DeleteFarFlungBarrel rather than explode them on map boundaries to save on performance
       
   147 -- utilized the improved AddCaption to tint / prevent overrides
       
   148 -- temporarily disabled bugged sort that displays teams according to their score
       
   149 -- reluctantly changed the colour of the bonus circ to purple
       
   150 -- standarized point notation
       
   151 -- added some missing locs
       
   152 -- commented out remaining WriteLnToConsoles for the meanwhile with the prefix "nw"
       
   153 
       
   154 -- ACHIEIVEMENTS added
       
   155 -- (during one turn) aka repeatable
       
   156 -- Ammo Manic (Destroy 3 green circles for + 5 points)
       
   157 -- Drone Hunter (Destroy 5 red circles for + 10 points)
       
   158 -- Shield Seeker (Destroy 3 purple circles for +10 points)
       
   159 -- Boss Slayer (Destroy 2 blue circles for +25 points)
       
   160 
       
   161 -- Shield Master (disolve 5 shells for +10 points)
       
   162 -- Shield Miser (don't use your shield at all (3.5*roundkills)+2 points)
       
   163 
       
   164 -- Depleted Kamikaze! (kamikaze into a blue/red circ when you are out of ammo) 5pts
       
   165 -- Timed Kamikaze! (kamikaze into a blue/red circ when you only have 5s left) 10pts
       
   166 -- Kamikaze Expert (combination of the above two) 15pts
       
   167 
       
   168 -- Multi-shot (destroy more than 1 invader with a single bullet) 15pts
       
   169 -- X-Hit Combo (destroy another invader in less than 3 seconds) chainLength*2 points
       
   170 
       
   171 -- Accuracy Bonus (80% accuracy at the end of your turn with more than 5 shots fired) 15pts
       
   172 
       
   173 --(during the length of the game) aka non-repeatable
       
   174 -- 10/25/50 kills (+25/+50/+100 points)
       
   175 
       
   176 -----------------
       
   177 --0.8
       
   178 -----------------
       
   179 -- added a HUD for turntimeleft, ammo, shield
       
   180 -- shieldhealth hits 0 properly
       
   181 
       
   182 ------------------------
       
   183 -- version 0.8.1
       
   184 ------------------------
       
   185 
       
   186 -- stop hiding non-existant 4th Tag
       
   187 -- redraw HUD on screen resolution change
       
   188 
       
   189 ------------------------
       
   190 -- version 0.9
       
   191 ------------------------
       
   192 -- time for more 'EXPERIMENTS' mwahahahahahaha D:
       
   193 -- (hopefully) balanced Shield Miser
       
   194 -- bosses are no longer a redunkulous 50 points, but toned down to 30
       
   195 -- experimental radar (it's INTERACTIVE and math-heavy :D) (visual gears are safe... right? D:)
       
   196 -- bugfix and balance for multishot
       
   197 
       
   198 ------------------------
       
   199 -- version 1.0
       
   200 ------------------------
       
   201 -- if only version numbers actually worked like this, wouldn't that be awful :D
       
   202 -- added surfer achievement
       
   203 -- increased value of shield miser by 1 point per kill (OP?)
       
   204 
       
   205 ------------------------
       
   206 -- version 1.1
       
   207 ------------------------
       
   208 -- fixed radar so that blips dont go past circs when you get very close
       
   209 -- added a missing loc for shield depletion
       
   210 -- increased delay to 1000 to try stop noobies missing their turn
       
   211 -- added sniper achievement for hits from over a 1000000 away
       
   212 -- added achievement for 3 "sniper" shots in a round
       
   213 -- added achievement for 3 "point blank" shots in a round
       
   214 -- added "fierce Competition" achievement for shooting an enemy hog (once per round)
       
   215 -- some support for more weapons later
       
   216 
       
   217 ------------------------
       
   218 -- version 1.2
       
   219 ------------------------
       
   220 -- show actual scores in stats screen
       
   221 -- show a couple of “awards” and more or less snarky comments in stats screen
       
   222 --  for various accomplisments and events those are just for fun, they don’t
       
   223 --  affect score or game outcome
       
   224 -- use script parameters for configuration, see top of file for more information
       
   225 -- stop overwriting game most scheme’s parameters
       
   226 -- disable weapon scheme
       
   227 -- play “denied” sound when trying to use empty radar, ammo or shield
       
   228 -- play “Hurry!” taunt when 5 seconds are left
       
   229 -- play throw sound when throwing a barrel
       
   230 -- play sonar sound for using radar
       
   231 -- play “Kamikaze!” taunt for receiving one of the kamikaze bonuses
       
   232 -- show total team score in HUD (white number)
       
   233 -- show message when trying to use empty radar
       
   234 -- show message when time’s up
       
   235 -- show message with round score at end of a round
       
   236 -- disabled health graph, replaced with score per round
       
   237 -- removed “selected weapon” message, we only have one weapon
       
   238 -- removed unused bubbleSort function
       
   239 -- play “Ooff” sound when hit by bazooka
       
   240 -- fix explosion being drawn twice when colliding with circle
       
   241 -- play explosion sound when barrel’s lifespan is over
       
   242 ]]
    83 ]]
   243 
    84 
   244 --------------------------
    85 --------------------------
   245 -- TODO list: notes for later
    86 -- TODO list: notes for later
   246 --------------------------
    87 --------------------------
   247 -- imitate winning animation at end instead of just ending the game
    88 -- imitate winning animation at end instead of just ending the game
   248 
    89 
   249 -- add support for other world edges (they are currently disabled)
    90 -- add support for other world edges (they are currently disabled)
   250 
    91 
   251 -- maybe add a check for a tie, IMPOSSIBRU THERE ARE NO TIES
    92 -- maybe add a check for a tie, IMPOSSIBRU THERE ARE NO TIES
   252 -- more achievements?
       
   253 -- more just-for-fun awards (for stats screen)
       
   254 
    93 
   255 -- if more weps are added, replace primshotsfired all over the place
    94 -- if more weps are added, replace primshotsfired all over the place
   256 
    95 
   257 -- look for derp and let invaders shoot again
    96 -- look for derp and let invaders shoot again
   258 
    97 
   263 
   102 
   264 -- some kind of ability-meter that lets you do something awesome when you are
   103 -- some kind of ability-meter that lets you do something awesome when you are
   265 -- doing really well in a given round.
   104 -- doing really well in a given round.
   266 -- probably new kind of shield that pops any invaders who come near
   105 -- probably new kind of shield that pops any invaders who come near
   267 
   106 
   268 -- fix game never ending bug
       
   269 -- fix radar
       
   270 -- new invader: golden snitch, doesn't show up on your radar
   107 -- new invader: golden snitch, doesn't show up on your radar
   271 
   108 
   272 -- maybe replace (48/100*vCircRadius[i])/2 with something better
   109 -- maybe replace (48/100*vCircRadius[i])/2 with something better
   273 
   110 
   274 
   111 
   275 ------- CODE FOLLOWS -------
   112 ------- CODE FOLLOWS -------
   276 
       
   277 
       
   278 --[[CAPTION CATEGORIES
       
   279 -----------------
       
   280 capgrpGameState
       
   281 -----------------
       
   282 AddCaption(LOC_NOT("Sniper!") .. " +10 " .. LOC_NOT("points") .. "!",0xffba00ff,capgrpAmmostate)
       
   283 --they call me bullsye
       
   284 --point blank combo
       
   285 --fierce Competition
       
   286 -----------------
       
   287 capgrpAmmostate
       
   288 -----------------
       
   289 AddCaption( chainLength .. LOC_NOT("-chain! +") .. chainLength*2 .. LOC_NOT(" points!"),0xffba00ff,capgrpAmmostate)
       
   290 AddCaption(LOC_NOT("Multi-shot! +15 points!"),0xffba00ff,capgrpAmmostate)
       
   291 
       
   292 -----------------
       
   293 capgrpAmmoinfo
       
   294 -----------------
       
   295 AddCaption(LOC_NOT("Shield Miser! +20 points!"),0xffba00ff,capgrpAmmoinfo)
       
   296 AddCaption(LOC_NOT("Shield Master! +10 points!"),0xffba00ff,capgrpAmmoinfo)
       
   297 
       
   298 -----------------
       
   299 capgrpVolume
       
   300 -----------------
       
   301 AddCaption(LOC_NOT("Boom! +25 points!"),0xffba00ff,capgrpVolume)
       
   302 AddCaption(LOC_NOT("BOOM! +50 points!"),0xffba00ff,capgrpVolume)
       
   303 AddCaption(LOC_NOT("BOOM! BOOM! BOOM! +100 points!"),0xffba00ff,capgrpVolume)
       
   304 AddCaption(LOC_NOT("Accuracy Bonus! +15 points!"),0xffba00ff,capgrpVolume)
       
   305 AddCaption(LOC_NOT("Surfer! +15 points!"),0xffba00ff,capgrpVolume)
       
   306 
       
   307 -----------------
       
   308 capgrpMessage
       
   309 -----------------
       
   310 AddCaption(LOC_NOT("Ammo Depleted!"),0xff0000ff,capgrpMessage)
       
   311 AddCaption(LOC_NOT("Ammo: ") .. primShotsLeft)
       
   312 AddCaption(LOC_NOT("Shield Depleted"),0xff0000ff,capgrpMessage)
       
   313 AddCaption( LOC_NOT("Shield ON:") .. " " .. shieldHealth - 80 .. " " .. LOC_NOT("Power Remaining") )
       
   314 AddCaption(LOC_NOT("Shield OFF:") .. " " .. shieldHealth - 80 .. " " .. LOC_NOT("Power Remaining") )
       
   315 
       
   316 AddCaption(LOC_NOT("Time Extended!") .. "+" .. 4 .. LOC_NOT("s"), 0xff0000ff,capgrpMessage )
       
   317 AddCaption("+" .. 3 .. " " .. LOC_NOT("Ammo"), 0x00ff00ff,capgrpMessage)
       
   318 AddCaption(LOC_NOT("Shield boosted! +30 power"), 0xff00ffff,capgrpMessage)
       
   319 AddCaption(LOC_NOT("Shield is fully recharged!"), 0xffae00ff,capgrpMessage)
       
   320 AddCaption(LOC_NOT("Boss defeated! +50 points!"), 0x0050ffff,capgrpMessage)
       
   321 
       
   322 AddCaption(LOC_NOT("GOTCHA!"))
       
   323 AddCaption(LOC_NOT("Kamikaze Expert! +15 points!"),0xffba00ff,capgrpMessage)
       
   324 AddCaption(LOC_NOT("Depleted Kamikaze! +5 points!"),0xffba00ff,capgrpMessage)
       
   325 AddCaption(LOC_NOT("Timed Kamikaze! +10 points!"),0xffba00ff,capgrpMessage)
       
   326 
       
   327 -----------------
       
   328 capgrpMessage2
       
   329 -----------------
       
   330 AddCaption(LOC_NOT("Drone Hunter! +10 points!"),0xffba00ff,capgrpMessage2)
       
   331 AddCaption(LOC_NOT("Ammo Maniac! +5 points!"),0xffba00ff,capgrpMessage2)
       
   332 AddCaption(LOC_NOT("Shield Seeker! +10 points!"),0xffba00ff,capgrpMessage2)
       
   333 AddCaption(LOC_NOT("Boss Slayer! +25 points!"),0xffba00ff,capgrpMessage2)
       
   334 ]]
       
   335 
   113 
   336 ----------------------------------
   114 ----------------------------------
   337 -- so I herd u liek wariables
   115 -- so I herd u liek wariables
   338 ----------------------------------
   116 ----------------------------------
   339 
   117 
   445 
   223 
   446 ----------------
   224 ----------------
   447 -- TUMBLER
   225 -- TUMBLER
   448 local wep = {}
   226 local wep = {}
   449 local wepAmmo = {}
   227 local wepAmmo = {}
   450 local wepCol = {}
       
   451 local wepIndex = 0
   228 local wepIndex = 0
   452 local wepCount = 0
   229 local wepCount = 0
   453 local fireTimer = 0
       
   454 ----------------
   230 ----------------
   455 
   231 
   456 
   232 
   457 
   233 
   458 local primShotsMax = 5
   234 local primShotsMax = 5
   577 				zoomL, 			--zoom
   353 				zoomL, 			--zoom
   578 				1, 			--~= 0 means align to screen
   354 				1, 			--~= 0 means align to screen
   579 				nil, 			--frameticks
   355 				nil, 			--frameticks
   580 				tValue, 		--value
   356 				tValue, 		--value
   581 				240000, 		--timer
   357 				240000, 		--timer
   582 				tCol		--GetClanColor( GetHogClan(CurrentHedgehog) )
   358 				tCol			--color
   583 				)
   359 				)
   584 
   360 
   585 end
   361 end
   586 
   362 
   587 function RebuildTeamInfo()
   363 function RebuildTeamInfo()
   958 	local lfs
   734 	local lfs
   959 	if GetGearType(gear) == gtShell then
   735 	if GetGearType(gear) == gtShell then
   960 		lfs = 50	-- roughly 5 seconds
   736 		lfs = 50	-- roughly 5 seconds
   961 		shellID = shellID + 1
   737 		shellID = shellID + 1
   962 		setGearValue(gear,"ID",shellID)
   738 		setGearValue(gear,"ID",shellID)
   963 		--nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this shell")
       
   964 	elseif GetGearType(gear) == gtBall then
   739 	elseif GetGearType(gear) == gtBall then
   965 		lfs = 5 --70	-- 7s
   740 		lfs = 5 --70	-- 7s
   966 	elseif GetGearType(gear) == gtExplosives then
   741 	elseif GetGearType(gear) == gtExplosives then
   967 		lfs = 15	-- 1.5s
   742 		lfs = 15	-- 1.5s
   968 		explosivesID = explosivesID + 1
   743 		explosivesID = explosivesID + 1
   969 		setGearValue(gear,"ID",explosivesID)
   744 		setGearValue(gear,"ID",explosivesID)
   970 		setGearValue(gear,"XP", GetX(gear))
   745 		setGearValue(gear,"XP", GetX(gear))
   971 		setGearValue(gear,"YP", GetY(gear))
   746 		setGearValue(gear,"YP", GetY(gear))
   972 		--nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this explosives")
       
   973 	elseif GetGearType(gear) == gtFlame then
   747 	elseif GetGearType(gear) == gtFlame then
   974 		lfs = 5	-- 0.5s
   748 		lfs = 5	-- 0.5s
   975 	else
   749 	else
   976 		lfs = 100
   750 		lfs = 100
   977 	end
   751 	end
   978 
   752 
   979 	setGearValue(gear,"lifespan",lfs)
   753 	setGearValue(gear,"lifespan",lfs)
   980 	--WriteLnToConsole("I also set its lifespan to " .. lfs)
       
   981 
       
   982 
   754 
   983 end
   755 end
   984 
   756 
   985 function HandleLifeSpan(gear)
   757 function HandleLifeSpan(gear)
   986 
   758 
   987 	decreaseGearValue(gear,"lifespan")
   759 	decreaseGearValue(gear,"lifespan")
   988 
       
   989 	--WriteLnToConsole("Just decreased the lifespan of a gear to " .. getGearValue(gear,"lifespan"))
       
   990 	--WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
   991 
       
   992 
   760 
   993 	if getGearValue(gear,"lifespan") == 0 then
   761 	if getGearValue(gear,"lifespan") == 0 then
   994 
   762 
   995 		if GetGearType(gear) == gtShell then
   763 		if GetGearType(gear) == gtShell then
   996 			AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false)
   764 			AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false)
   997 
       
   998 			WriteLnToConsole("about to delete a shell due to lifespan == 0")
       
   999 		elseif GetGearType(gear) == gtExplosives then
   765 		elseif GetGearType(gear) == gtExplosives then
  1000 			AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
   766 			AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  1001 			PlaySound(sndExplosion)
   767 			PlaySound(sndExplosion)
  1002 		elseif GetGearType(gear) == gtFlame then
   768 		elseif GetGearType(gear) == gtFlame then
  1003 			AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false)
   769 			AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false)
  1017 			(GetX(gear) > 6200) or
   783 			(GetX(gear) > 6200) or
  1018 			(GetY(gear) < -3400)
   784 			(GetY(gear) < -3400)
  1019 		then
   785 		then
  1020 			AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
   786 			AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  1021 			DeleteGear(gear)
   787 			DeleteGear(gear)
  1022 			--WriteLnToConsole("I'm setting barrel ID " .. getGearValue(gear,"ID") .. " to 0 health because it's been flung too close to the map edges. at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
  1023 		end
   788 		end
  1024 
   789 
  1025 	end
   790 	end
  1026 
   791 
  1027 end
   792 end
  1035 
   800 
  1036 	wepIndex = wepIndex + 1
   801 	wepIndex = wepIndex + 1
  1037 	if wepIndex == wepCount then
   802 	if wepIndex == wepCount then
  1038 		wepIndex = 0
   803 		wepIndex = 0
  1039 	end
   804 	end
  1040 
       
  1041 --[[
       
  1042 	NOTE: Don’t show selected weapon as long we only have one. Remove this comment and activate this code
       
  1043 	again as soon as at least one other weapon appears.
       
  1044 	AddCaption(wep[wepIndex] .. " " .. loc("selected!"), wepCol[wepIndex],capgrpAmmoinfo )
       
  1045 	AddCaption(wepAmmo[wepIndex] .. " " .. loc("shots remaining."), wepCol[wepIndex],capgrpMessage2)
       
  1046 ]]
       
  1047 
       
  1048 end
   805 end
  1049 
   806 
  1050 -- derp tumbler
   807 -- derp tumbler
  1051 function onPrecise()
   808 function onPrecise()
  1052 
   809 
  1056 
   813 
  1057 		if wep[wepIndex] == loc("Barrel Launcher") then
   814 		if wep[wepIndex] == loc("Barrel Launcher") then
  1058 			shotsFired = shotsFired +1
   815 			shotsFired = shotsFired +1
  1059 
   816 
  1060 			local morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtExplosives, 0, 0, 0, 1)
   817 			local morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtExplosives, 0, 0, 0, 1)
  1061 			CopyPV(CurrentHedgehog, morte) -- new addition
   818 			CopyPV(CurrentHedgehog, morte)
  1062 			local x,y = GetGearVelocity(morte)
   819 			local x,y = GetGearVelocity(morte)
  1063 			x = x*2
   820 			x = x*2
  1064 			y = y*2
   821 			y = y*2
  1065 			SetGearVelocity(morte, x, y)
   822 			SetGearVelocity(morte, x, y)
  1066 
   823 
  1242 
   999 
  1243 	wep[0] = loc("Barrel Launcher")
  1000 	wep[0] = loc("Barrel Launcher")
  1244 	wep[1] = loc("Mine Deployer")
  1001 	wep[1] = loc("Mine Deployer")
  1245 	wep[2] = loc("Flamer")
  1002 	wep[2] = loc("Flamer")
  1246 
  1003 
  1247 	wepCol[0] = 0x78818eff
       
  1248 	wepCol[1] = 0xa12a77ff
       
  1249 	wepCol[2] = 0xf49318ff
       
  1250 
       
  1251 	wepCount = 3
  1004 	wepCount = 3
  1252 
  1005 
  1253 end
  1006 end
  1254 
  1007 
  1255 function onGameStart()
  1008 function onGameStart()
  1372 		HideTag(TAG_BARRELS)
  1125 		HideTag(TAG_BARRELS)
  1373 		HideTag(TAG_SHIELD)
  1126 		HideTag(TAG_SHIELD)
  1374 		HideTag(TAG_ROUND_SCORE)
  1127 		HideTag(TAG_ROUND_SCORE)
  1375 	end
  1128 	end
  1376 
  1129 
  1377 	---------------
       
  1378 	---------------
       
  1379 	--AddCaption("num g: " .. numGears() )
       
  1380 	--WriteLnToConsole("onNewTurn, I just set a bunch of variables to their necessary states. This was done at:")
       
  1381 	--WriteLnToConsole("The above occured at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
  1382 
       
  1383 end
  1130 end
  1384 
  1131 
  1385 function ThingsToBeRunOnGears(gear)
  1132 function ThingsToBeRunOnGears(gear)
  1386 
  1133 
  1387 	HandleLifeSpan(gear)
  1134 	HandleLifeSpan(gear)
  1408 	end
  1155 	end
  1409 end
  1156 end
  1410 
  1157 
  1411 function onGameTick()
  1158 function onGameTick()
  1412 
  1159 
  1413 
  1160 	luaGameTicks = luaGameTicks + 1
  1414 	--WriteLnToConsole("Start of GameTick")
       
  1415 	luaGameTicks = luaGameTicks + 1 -- GameTime
       
  1416 
  1161 
  1417 	HandleCircles()
  1162 	HandleCircles()
  1418 
  1163 
  1419 	timer100 = timer100 + 1
  1164 	timer100 = timer100 + 1
  1420 	if timer100 >= 100 then
  1165 	if timer100 >= 100 then
  1421 		timer100 = 0
  1166 		timer100 = 0
  1422 
  1167 
  1423 		if beam == true then
  1168 		if beam == true then
  1424 			shieldHealth = shieldHealth - 1
  1169 			shieldHealth = shieldHealth - 1
  1425 			if shieldHealth < 80 then -- <= 80
  1170 			if shieldHealth < 80 then
  1426 				shieldHealth = 80
  1171 				shieldHealth = 80
  1427 				beam = false
  1172 				beam = false
  1428 				AddCaption(loc("Shield depleted"),0xff0000ff,capgrpMessage)
  1173 				AddCaption(loc("Shield depleted"),0xff0000ff,capgrpMessage)
  1429 				PlaySound(sndMineTick)
  1174 				PlaySound(sndMineTick)
  1430 				PlaySound(sndSwitchHog)
  1175 				PlaySound(sndSwitchHog)
  1436 			if tauntTimer <= 0 and tumbleStarted and not stopMovement then
  1181 			if tauntTimer <= 0 and tumbleStarted and not stopMovement then
  1437 				PlaySound(tauntSound, tauntGear)
  1182 				PlaySound(tauntSound, tauntGear)
  1438 			end
  1183 			end
  1439 		end
  1184 		end
  1440 
  1185 
  1441 		--nw WriteLnToConsole("Starting ThingsToBeRunOnGears()")
       
  1442 
       
  1443 		runOnGears(ThingsToBeRunOnGears)
  1186 		runOnGears(ThingsToBeRunOnGears)
  1444 
       
  1445 		--nw WriteLnToConsole("Finished ThingsToBeRunOnGears()")
       
  1446 
  1187 
  1447 		if circlesAreGo == true then
  1188 		if circlesAreGo == true then
  1448 			CheckDistances()
  1189 			CheckDistances()
  1449 		end
  1190 		end
  1450 
  1191 
  1453 			local j,k = GetGearVelocity(CurrentHedgehog)
  1194 			local j,k = GetGearVelocity(CurrentHedgehog)
  1454 			if (j ~= 0) and (k ~= 0) then
  1195 			if (j ~= 0) and (k ~= 0) then
  1455 				AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true)
  1196 				AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true)
  1456 			end
  1197 			end
  1457 		end
  1198 		end
  1458 
       
  1459 		--nw WriteLnToConsole("Finished 100Timer")
       
  1460 
  1199 
  1461 	end
  1200 	end
  1462 
  1201 
  1463 
  1202 
  1464 	-- start the player tumbling with a boom once their turn has actually begun
  1203 	-- start the player tumbling with a boom once their turn has actually begun
  1475 			DrawTag(TAG_ROUND_SCORE)
  1214 			DrawTag(TAG_ROUND_SCORE)
  1476 			SetMyCircles(true)
  1215 			SetMyCircles(true)
  1477 		end
  1216 		end
  1478 	end
  1217 	end
  1479 
  1218 
  1480 	--WriteLnToConsole("Finished initial check")
       
  1481 
       
  1482 	if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then
  1219 	if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then
  1483 
  1220 
  1484 		-- Calculate and display turn time
  1221 		-- Calculate and display turn time
  1485 		TimeLeftCounter = TimeLeftCounter + 1
  1222 		TimeLeftCounter = TimeLeftCounter + 1
  1486 		if TimeLeftCounter == 1000 then
  1223 		if TimeLeftCounter == 1000 then
  1498 				PlaySound(sndHurry, CurrentHedgehog)
  1235 				PlaySound(sndHurry, CurrentHedgehog)
  1499 			elseif TimeLeft <= 4 and TimeLeft >= 1 then
  1236 			elseif TimeLeft <= 4 and TimeLeft >= 1 then
  1500 				PlaySound(_G["sndCountdown"..TimeLeft])
  1237 				PlaySound(_G["sndCountdown"..TimeLeft])
  1501 			end
  1238 			end
  1502 		end
  1239 		end
  1503 
       
  1504 		--WriteLnToConsole("Finished timeleft calculations")
       
  1505 
  1240 
  1506 		-------------------------------
  1241 		-------------------------------
  1507 		-- Player has run out of luck (out of time or hit by gtShell)
  1242 		-- Player has run out of luck (out of time or hit by gtShell)
  1508 		-------------------------------
  1243 		-------------------------------
  1509 		-- checks in FloatyThings
  1244 		-- checks in FloatyThings
  1510 		if PlayerIsFine() == false then
  1245 		if PlayerIsFine() == false then
  1511 			TimeLeft = 0
  1246 			TimeLeft = 0
  1512 		end
  1247 		end
  1513 
       
  1514 		--WriteLnToConsole("successfully checked playerIsFine")
       
  1515 
  1248 
  1516 		if (TimeLeft == 0) then
  1249 		if (TimeLeft == 0) then
  1517 			if PlayerIsFine() then AddCaption(loc("Time's up!")) end
  1250 			if PlayerIsFine() then AddCaption(loc("Time's up!")) end
  1518 			if (stopMovement == false) then	--time to stop the player
  1251 			if (stopMovement == false) then	--time to stop the player
  1519 				stopMovement = true
  1252 				stopMovement = true
  1524 				leftOn = false
  1257 				leftOn = false
  1525 				rightOn = false
  1258 				rightOn = false
  1526 				SetMyCircles(false)
  1259 				SetMyCircles(false)
  1527 				rAlpha = 255
  1260 				rAlpha = 255
  1528 				FailGraphics()
  1261 				FailGraphics()
  1529 				--nw WriteLnToConsole("Player is out of luck")
       
  1530 
  1262 
  1531 				if shieldMiser == true then
  1263 				if shieldMiser == true then
  1532 
  1264 
  1533 					local p = (roundKills*3.5) - ((roundKills*3.5)%1) + 2
  1265 					local p = (roundKills*3.5) - ((roundKills*3.5)%1) + 2
  1534 
  1266 
  1573 		else -- remove this if you want tumbler to fall slowly on death
  1305 		else -- remove this if you want tumbler to fall slowly on death
  1574 		-------------------------------
  1306 		-------------------------------
  1575 		-- Player is still in luck
  1307 		-- Player is still in luck
  1576 		-------------------------------
  1308 		-------------------------------
  1577 
  1309 
  1578 
       
  1579 			--WriteLnToConsole("about to do chainCounter checks")
       
  1580 			if chainCounter > 0 then
  1310 			if chainCounter > 0 then
  1581 				chainCounter = chainCounter -1
  1311 				chainCounter = chainCounter -1
  1582 				if chainCounter == 0 then
  1312 				if chainCounter == 0 then
  1583 					chainLength = 0
  1313 					chainLength = 0
  1584 				end
  1314 				end
  1585 			end
  1315 			end
  1586 
  1316 
  1587 			-- handle movement based on IO
  1317 			-- handle movement based on IO
  1588 			moveTimer = moveTimer + 1
  1318 			moveTimer = moveTimer + 1
  1589 			if moveTimer == 100 then -- 100
  1319 			if moveTimer == 100 then -- 100
  1590 				--nw WriteLnToConsole("Start of Player MoveTimer")
       
  1591 				moveTimer = 0
  1320 				moveTimer = 0
  1592 
  1321 
  1593 				---------------
  1322 				---------------
  1594 				-- new trail code
  1323 				-- new trail code
  1595 				---------------
  1324 				---------------
  1600 				end
  1329 				end
  1601 				--------------
  1330 				--------------
  1602 				--------------
  1331 				--------------
  1603 
  1332 
  1604 				local dx, dy = GetGearVelocity(CurrentHedgehog)
  1333 				local dx, dy = GetGearVelocity(CurrentHedgehog)
  1605 
       
  1606 				--WriteLnToConsole("I just got the velocity of currenthedgehog. It is dx: " .. dx .. "; dy: " .. dy)
       
  1607 				--WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
  1608 
  1334 
  1609 				local dxlimit, dylimit
  1335 				local dxlimit, dylimit
  1610 				if boosterOn == true then
  1336 				if boosterOn == true then
  1611 					local tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtDust, 0, false)
  1337 					local tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtDust, 0, false)
  1612 					SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, 1, nil, GetClanColor(GetHogClan(CurrentHedgehog)) )
  1338 					SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, 1, nil, GetClanColor(GetHogClan(CurrentHedgehog)) )
  1645 					dy = dy + 0.1*fMod
  1371 					dy = dy + 0.1*fMod
  1646 				end
  1372 				end
  1647 
  1373 
  1648 				SetGearVelocity(CurrentHedgehog, dx, dy)
  1374 				SetGearVelocity(CurrentHedgehog, dx, dy)
  1649 
  1375 
  1650 				--WriteLnToConsole("I just SET the velocity of currenthedgehog. It is now dx: " .. dx .. "; dy: " .. dy)
       
  1651 				--WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
  1652 				--nw WriteLnToConsole("End of Player MoveTimer")
       
  1653 
       
  1654 			end
  1376 			end
  1655 
  1377 
  1656 
  1378 
  1657 		end -- new end I put here to check if he's still alive or not
  1379 		end -- new end I put here to check if he's still alive or not
  1658 
  1380 
  1659 	end
  1381 	end
  1660 
       
  1661 	--WriteLnToConsole("End of GameTick")
       
  1662 
  1382 
  1663 end
  1383 end
  1664 
  1384 
  1665 function onGearDamage(gear, damage)
  1385 function onGearDamage(gear, damage)
  1666 	if GetGearType(gear) == gtHedgehog and damage >= 60 then
  1386 	if GetGearType(gear) == gtHedgehog and damage >= 60 then
  1696 
  1416 
  1697 	-- did I fall into the water? well, that was a stupid thing to do
  1417 	-- did I fall into the water? well, that was a stupid thing to do
  1698 	if gear == CurrentHedgehog then
  1418 	if gear == CurrentHedgehog then
  1699 		TimeLeft = 0
  1419 		TimeLeft = 0
  1700 		playerIsFine = false
  1420 		playerIsFine = false
  1701 		--WriteLnToConsole("Current hedgehog just drowned himself")
       
  1702 		--WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
       
  1703 	end
  1421 	end
  1704 
  1422 
  1705 end
  1423 end
  1706 
  1424 
  1707 function onGearAdd(gear)
  1425 function onGearAdd(gear)
  2067 	SetVisualGearValues(rCirc[i], 0, 0, nil, nil, nil, nil, nil, nil, nil, vCircCol[i]-0x000000ff)
  1785 	SetVisualGearValues(rCirc[i], 0, 0, nil, nil, nil, nil, nil, nil, nil, vCircCol[i]-0x000000ff)
  2068 
  1786 
  2069 
  1787 
  2070 	vCircActive[i] = true
  1788 	vCircActive[i] = true
  2071 
  1789 
  2072 	--nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i])
       
  2073 	--nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i])
       
  2074 	--nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i])
       
  2075 
       
  2076 end
  1790 end
  2077 
  1791 
  2078 function SetMyCircles(s)
  1792 function SetMyCircles(s)
  2079 
  1793 
  2080 	circlesAreGo = s
  1794 	circlesAreGo = s
  2081 	playerIsFine = s
  1795 	playerIsFine = s
  2082 
  1796 
  2083 	if s == true then
       
  2084 		--nw WriteLnToConsole("About to set up all circles, old values are here:")
       
  2085 		for i = 0,(vCCount-1) do
       
  2086 			--nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i])
       
  2087 			--nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i])
       
  2088 			--nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i])
       
  2089 		end
       
  2090 		--nw WriteLnToConsole("Old values given, new values to follow...")
       
  2091 	end
       
  2092 
       
  2093 	for i = 0,(vCCount-1) do
  1797 	for i = 0,(vCCount-1) do
  2094 
  1798 
  2095 		if s == false then
  1799 		if s == false then
  2096 			--vCircCol[i] = 0xffffffff
       
  2097 			vCircActive[i] = false
  1800 			vCircActive[i] = false
  2098 		elseif s == true then
  1801 		elseif s == true then
  2099 			SetUpCircle(i)
  1802 			SetUpCircle(i)
  2100 		end
  1803 		end
  2101 
  1804 
  2139 	if (GetGearType(gear) == gtExplosives) then
  1842 	if (GetGearType(gear) == gtExplosives) then
  2140 		local circsHit = 0
  1843 		local circsHit = 0
  2141 
  1844 
  2142 		for i = 0,(vCCount-1) do
  1845 		for i = 0,(vCCount-1) do
  2143 
  1846 
  2144 			--nw WriteLnToConsole("Is it neccessary to check for collision with circ " .. i)
       
  2145 
       
  2146 			--nw WriteLnToConsole("YES. about to calc distance between gtExplosives and circ " .. i)
       
  2147 
       
  2148 			local dist = GetDistFromGearToXY(gear, vCircX[i], vCircY[i])
  1847 			local dist = GetDistFromGearToXY(gear, vCircX[i], vCircY[i])
  2149 
  1848 
  2150 			-- calculate my real radius if I am an aura
  1849 			-- calculate my real radius if I am an aura
  2151 			local NR
  1850 			local NR
  2152 			if vCircType[i] == 0 then
  1851 			if vCircType[i] == 0 then
  2154 			else
  1853 			else
  2155 				NR = (48/100*vCircRadius[i])/2
  1854 				NR = (48/100*vCircRadius[i])/2
  2156 			end
  1855 			end
  2157 
  1856 
  2158 			if dist <= NR*NR then
  1857 			if dist <= NR*NR then
  2159 
       
  2160 
       
  2161 				--nw WriteLnToConsole("Collision confirmed. The gtExplosives is within the circ radius!")
       
  2162 
  1858 
  2163 				dist = (GetDistFromXYtoXY(vCircX[i], vCircY[i], getGearValue(gear,"XP"), getGearValue(gear,"YP")) - (NR*NR))
  1859 				dist = (GetDistFromXYtoXY(vCircX[i], vCircY[i], getGearValue(gear,"XP"), getGearValue(gear,"YP")) - (NR*NR))
  2164 				if dist >= 1000000 then
  1860 				if dist >= 1000000 then
  2165 					sniperHits = sniperHits +1
  1861 					sniperHits = sniperHits +1
  2166 					AddCaption(loc("Sniper! +8 points!"),0xffba00ff,capgrpGameState)
  1862 					AddCaption(loc("Sniper! +8 points!"),0xffba00ff,capgrpGameState)
  2180 				end
  1876 				end
  2181 
  1877 
  2182 				AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  1878 				AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  2183 
  1879 
  2184 				targetHit = true
  1880 				targetHit = true
  2185 				--WriteLnToConsole("set " .. "Exp ID: " .. getGearValue(gear,"ID") .. " health to 0")
       
  2186 				--WriteLnToConsole("targetHit set to true, explosive is at distance " .. dist .. "(within range " .. NR*NR.. ") of circ" )
       
  2187 
       
  2188 				CircleDamaged(i)
  1881 				CircleDamaged(i)
  2189 
  1882 
  2190 				circsHit = circsHit + 1
  1883 				circsHit = circsHit + 1
  2191 				if circsHit > 1 then
  1884 				if circsHit > 1 then
  2192 					AddCaption(loc("Multi-shot! +15 points!"),0xffba00ff,capgrpAmmostate)
  1885 					AddCaption(loc("Multi-shot! +15 points!"),0xffba00ff,capgrpAmmostate)
  2226 		end
  1919 		end
  2227 
  1920 
  2228 	end
  1921 	end
  2229 
  1922 
  2230 	if targetHit == true then
  1923 	if targetHit == true then
  2231 			--nw WriteLnToConsole("about to delete something due to targetHit being set to true earlier")
  1924 		DeleteGear(gear)
  2232 			DeleteGear(gear)
  1925 	end
  2233 			--nw WriteLnToConsole("there, I deleted it")
       
  2234 	end
       
  2235 
       
  2236 	--nw WriteLnToConsole("End of CheckVarious()")
       
  2237 
  1926 
  2238 end
  1927 end
  2239 
  1928 
  2240 -- collision detection for player entering a circle
  1929 -- collision detection for player entering a circle
  2241 function CheckDistances()
  1930 function CheckDistances()
  2242 
  1931 
  2243 	if not CurrentHedgehog then
  1932 	if not CurrentHedgehog then
  2244 		return
  1933 		return
  2245 	end
  1934 	end
  2246 	--nw WriteLnToConsole("Start of CheckDistances()")
       
  2247 
  1935 
  2248 	for i = 0,(vCCount-1) do
  1936 	for i = 0,(vCCount-1) do
  2249 
       
  2250 
       
  2251 		--nw WriteLnToConsole("Attempting to calculate dist of circ " .. i)
       
  2252 
  1937 
  2253 		local g1X, g1Y = GetGearPosition(CurrentHedgehog)
  1938 		local g1X, g1Y = GetGearPosition(CurrentHedgehog)
  2254 		local g2X, g2Y = vCircX[i], vCircY[i]
  1939 		local g2X, g2Y = vCircX[i], vCircY[i]
  2255 
  1940 
  2256 		g1X = g1X - g2X
  1941 		g1X = g1X - g2X
  2257 		g1Y = g1Y - g2Y
  1942 		g1Y = g1Y - g2Y
  2258 		local dist = (g1X*g1X) + (g1Y*g1Y)
  1943 		local dist = (g1X*g1X) + (g1Y*g1Y)
  2259 
       
  2260 		--nw WriteLnToConsole("Calcs done. Dist to CurrentHedgehog is " .. dist)
       
  2261 
  1944 
  2262 		-- calculate my real radius if I am an aura
  1945 		-- calculate my real radius if I am an aura
  2263 		local NR
  1946 		local NR
  2264 		if vCircType[i] == 0 then
  1947 		if vCircType[i] == 0 then
  2265 			NR = vCircRadius[i]
  1948 			NR = vCircRadius[i]
  2309 
  1992 
  2310 		end
  1993 		end
  2311 
  1994 
  2312 	end
  1995 	end
  2313 
  1996 
  2314 	--nw WriteLnToConsole("End of CheckDistances()")
       
  2315 
       
  2316 end
  1997 end
  2317 
  1998 
  2318 function HandleCircles()
  1999 function HandleCircles()
  2319 
  2000 
  2320 	if rAlpha ~= 255 then
  2001 	if rAlpha ~= 255 then
  2392 				elseif vType[i] == "blueboss" then
  2073 				elseif vType[i] == "blueboss" then
  2393 
  2074 
  2394 					local k = 25
  2075 					local k = 25
  2395 					local g = vgtSteam
  2076 					local g = vgtSteam
  2396 					local trailColour = 0xae00ffff
  2077 					local trailColour = 0xae00ffff
  2397 
       
  2398 					-- 0xffae00ff -- orange
       
  2399 					-- 0xae00ffff -- purp
       
  2400 
  2078 
  2401 					local tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
  2079 					local tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
  2402 					SetVisualGearValues(tempE, vCircX[i], vCircY[i]+k, nil, nil, nil, nil, nil, nil, nil, trailColour-75 )
  2080 					SetVisualGearValues(tempE, vCircX[i], vCircY[i]+k, nil, nil, nil, nil, nil, nil, nil, trailColour-75 )
  2403 
  2081 
  2404 					tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
  2082 					tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
  2528 
  2206 
  2529 function ProjectileTrack(gear)
  2207 function ProjectileTrack(gear)
  2530 
  2208 
  2531 	if (GetGearType(gear) == gtShell) then
  2209 	if (GetGearType(gear) == gtShell) then
  2532 
  2210 
  2533 		--nw WriteLnToConsole("ProjectileTrack() for Shell ID: " .. getGearValue(gear,"ID"))
       
  2534 
       
  2535 		local turningSpeed = 0.1*fMod
  2211 		local turningSpeed = 0.1*fMod
  2536 
  2212 
  2537 		local dx, dy = GetGearVelocity(gear)
  2213 		local dx, dy = GetGearVelocity(gear)
  2538 
       
  2539 		--WriteLnToConsole("I'm trying to track currenthedge with shell ID: " .. getGearValue(gear,"ID"))
       
  2540 		--WriteLnToConsole("I just got the velocity of the shell. It is dx: " .. dx .. "; dy: " .. dy)
       
  2541 		--WriteLnToConsole("CurrentHedgehog is at X: " .. GetX(CurrentHedgehog) .. "; Y: " .. GetY(CurrentHedgehog) )
       
  2542 
  2214 
  2543 		if GetX(gear) > GetX(CurrentHedgehog) then
  2215 		if GetX(gear) > GetX(CurrentHedgehog) then
  2544 			dx = dx - turningSpeed
  2216 			dx = dx - turningSpeed
  2545 		else
  2217 		else
  2546 			dx = dx + turningSpeed
  2218 			dx = dx + turningSpeed
  2569 			dy = -dylimit
  2241 			dy = -dylimit
  2570 		end
  2242 		end
  2571 
  2243 
  2572 		SetGearVelocity(gear, dx, dy)
  2244 		SetGearVelocity(gear, dx, dy)
  2573 
  2245 
  2574 		--WriteLnToConsole("I just SET the velocity of shell towards currenthegdge. It is now dx: " .. dx .. "; dy: " .. dy)
  2246 	end
  2575 		--WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
  2247 
  2576 		--nw WriteLnToConsole("ProjectileTrack() finished successfully")
  2248 end
  2577 
  2249 
  2578 	end
       
  2579 
       
  2580 end
       
  2581