Advertisement
Lethanov

Horde.Script.txt

Jul 10th, 2013
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.37 KB | None | 0 0
  1. #RequireContext CSmMode
  2.  
  3. #Const CompatibleMapTypes "HordeArena"
  4. #Const Version "2013-02-13"
  5.  
  6. #Include "MathLib" as MathLib
  7. #Include "TextLib" as TextLib
  8. #Include "Libs/Nadeo/Mode.Script.txt" as Mode
  9. #Include "Libs/Nadeo/Shootmania/SM.Script.txt" as SM
  10. #Include "Libs/Nadeo/Message.Script.txt" as Message
  11.  
  12. // Game over condition : a certain amount of bots reach the pole(s)
  13. #Const C_LimitNbBotReachedPole 10.
  14.  
  15. // Pole capture parameters
  16. #Const C_PoleCaptureRadius 4.
  17.  
  18. // Bots parameters
  19. #Const C_BotArmor 200
  20. #Const C_BotAggroRadius 5.
  21. #Const C_BotDisengageDistance 20.
  22. #Const C_BotShootPeriodMin 1000
  23. #Const C_BotShootPeriodMax 1000
  24. #Const C_BotAccuracy 1.
  25. #Const C_BotReactionTime 100
  26. #Const C_BotRocketAnticipation False
  27.  
  28. // Waves parameters
  29. #Const C_NbBotsPerWave 4
  30. #Const C_BotsFirstSpawnDelay 5000
  31. #Const C_BotsSpawnDeltaTime 500
  32. #Const C_BotsWavesSpawnDeltaTime 15000 // Useless when C_SpawnWaitWaveCleared == True
  33. #Const C_NbWavesBeforeInsaneMode 10
  34.  
  35. // Reload when hit
  36. #Const C_AmmoGainOnHit 0.6
  37.  
  38. // Growing difficulty
  39. #Const C_MaxDifficulty 9
  40. #Const C_Levels_SpeedPower[0.2, 0.4, 0.6, 0.6, 0.8, 0.8, 1., 1., 1., 1.]
  41.  
  42. // Frenzy
  43. #Const C_BaseAmmoGainMultiplier 1.
  44. #Const C_FrenzyAmmoGainMultiplier 3.
  45. #Const C_FrenzyThreshold 10
  46. #Const C_FrenzyDuration 10000
  47.  
  48. // Maximum number of bots at the same time
  49. #Const MaximumBotsNb 50
  50.  
  51. // Players are in one clan and bots in another
  52. #Const C_PlayerClan 1
  53.  
  54. // Refers to the custom model for our minions
  55. declare Ident ModelId;
  56.  
  57. Text TimeMsToString(Integer _Time)
  58. {
  59. declare Millis = _Time%1000;
  60. declare Secs = (_Time/1000)%60;
  61. declare Mins = _Time/60000;
  62.  
  63. return Mins^" m "^Secs^" s "^Millis^" ms";
  64. }
  65.  
  66. Void SpawnBotPlayer(Integer _Clan, Integer _Armor, CSmLandmark _BotSpawn, Integer _Time, Integer _Difficulty)
  67. {
  68. declare BotPlayer = CreateBotPlayer(ModelId, _Clan, _Armor, _BotSpawn, _Time);
  69. assert (BotPlayer != Null && BotPlayer.Driver != Null);
  70. BotPlayer.Driver.Behaviour = CSmPlayerDriver::ESmDriverBehaviour::Patrol;
  71. BotPlayer.Driver.ShootPeriodMin = C_BotShootPeriodMin;
  72. BotPlayer.Driver.ShootPeriodMax = C_BotShootPeriodMax;
  73. BotPlayer.Driver.Accuracy = C_BotAccuracy;
  74. BotPlayer.Driver.ReactionTime = C_BotReactionTime;
  75. BotPlayer.Driver.RocketAnticipation = C_BotRocketAnticipation;
  76. BotPlayer.Driver.DisengageDistance = C_BotDisengageDistance;
  77. BotPlayer.Driver.AggroRadius = C_BotAggroRadius;
  78. BotPlayer.EnergyLevel = 0.;
  79. BotPlayer.SpeedPower = C_Levels_SpeedPower[_Difficulty];
  80. }
  81.  
  82. Void UnspawnEveryone()
  83. {
  84.  
  85. foreach(Player in BotPlayers)
  86. {
  87. DestroyBotPlayer(Player);
  88. }
  89. //DestroyAllBotPlayers();
  90.  
  91. foreach(Player in Players)
  92. {
  93. UnspawnPlayer(Player);
  94. }
  95. }
  96.  
  97. Void CheckRecords(Integer _Time)
  98. {
  99. // Medal times are saved in the map (check "Set map objectives" to change them)
  100. declare metadata Integer ObjectiveAuthor for Map;
  101. declare metadata Integer ObjectiveGold for Map;
  102. declare metadata Integer ObjectiveSilver for Map;
  103. declare metadata Integer ObjectiveBronze for Map;
  104.  
  105. UIManager.UIAll.StatusMessage = "Your time : "^TimeMsToString(_Time);
  106.  
  107. if (_Time >= ObjectiveAuthor)
  108. UIManager.UIAll.BigMessage = "Game over, you won the Author medal!";
  109. else if (_Time >= ObjectiveGold)
  110. UIManager.UIAll.BigMessage = "Game over, you won the Gold medal!";
  111. else if (_Time >= ObjectiveSilver)
  112. UIManager.UIAll.BigMessage = "Game over, you won the Silver medal!";
  113. else if (_Time >= ObjectiveBronze)
  114. UIManager.UIAll.BigMessage = "Game over, you won the Bronze medal!";
  115. else
  116. UIManager.UIAll.BigMessage = "Game over, you lost !";
  117. }
  118.  
  119. Void ResetUI()
  120. {
  121. UIManager.UIAll.BigMessage = "";
  122. UIManager.UIAll.StatusMessage = "";
  123.  
  124. foreach(Player in Players)
  125. {
  126. declare CUIConfig UI;
  127. UI <=> UIManager.GetUI(Player);
  128.  
  129. UI.BigMessage = "";
  130. UI.StatusMessage = "";
  131. UI.ManialinkPage = """""";
  132. }
  133. }
  134.  
  135. Integer DoTry()
  136. {
  137. StartTime = Now;
  138.  
  139. declare TimeLastBotReachedPole = Now;
  140. declare NextBotSpawnTime = Now + C_BotsFirstSpawnDelay;
  141. declare LatestBotSpawnTime = 0;
  142. declare NbBotsReachedPole = 0;
  143.  
  144. // Growing difficulty
  145. declare Difficulty = 9;
  146. declare LastDifficultyLevelUp = 0;
  147. declare BotsArmorBonus = 0;
  148.  
  149. // Insane mode
  150. declare NbWavesSpawned = 0;
  151.  
  152. foreach(Player in Players)
  153. {
  154. Player.AmmoGain = 1. * C_BaseAmmoGainMultiplier;
  155. }
  156.  
  157. // Game ends when a certain amount of bots reach the pole(s)
  158. while(!ServerShutdownRequested && !MatchEndRequested && NbBotsReachedPole < C_LimitNbBotReachedPole)
  159. {
  160. yield;
  161.  
  162. ResetUI();
  163.  
  164. // Events management
  165. foreach(Event in PendingEvents)
  166. {
  167. if(Event.Type == CSmModeEvent::EType::OnPlayerRequestRespawn)
  168. {
  169. PassOn(Event);
  170. }
  171. if(Event.Type == CSmModeEvent::EType::OnArmorEmpty)
  172. {
  173. PassOn(Event);
  174. }
  175. else if(Event.Type == CSmModeEvent::EType::OnHit)
  176. {
  177. if (Event.Shooter != Null && Event.Victim != Null)
  178. {
  179. if(Event.Victim == Event.Shooter || Event.Victim.CurrentClan == Event.Shooter.CurrentClan)
  180. {
  181. Discard(Event);
  182. continue;
  183. }
  184.  
  185. // Reloads laser
  186. if(Event.WeaponNum == 1)
  187. {
  188. AddPlayerAmmo(Event.Shooter,CSmMode::EWeapon::Laser, C_AmmoGainOnHit);
  189. declare CurrentHitStreak for Event.Shooter = 0;
  190. CurrentHitStreak += 1;
  191. }
  192. }
  193.  
  194. PassOn(Event);
  195. }
  196. else if(Event.Type == CSmModeEvent::EType::OnShoot)
  197. {
  198. if(Event.Shooter != Null && !Event.Shooter.IsBot && Event.WeaponNum == 1)
  199. {
  200. declare CurrentShotNb for Event.Shooter = 0;
  201. CurrentShotNb += 1;
  202. }
  203. }
  204. }
  205.  
  206. foreach(Player in Players)
  207. {
  208. if(Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned)
  209. {
  210. SetPlayerWeapon(Player, CSmMode::EWeapon::Laser, False);
  211. SpawnPlayer(Player, C_PlayerClan, Player.ArmorMax, BlockSpawns[0], Now);
  212. }
  213. }
  214.  
  215. foreach(Bot in BotPlayers)
  216. {
  217. // Destroys unspawned bots
  218. if(Bot.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned)
  219. {
  220. DestroyBotPlayer(Bot);
  221. }
  222. else if(Bot.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned)
  223. {
  224. // Check if the bot is close to a pole
  225. foreach (BlockPole in BlockPoles)
  226. {
  227. declare Distance = MathLib::Distance(Bot.Position, BlockPole.Position);
  228. if(Distance < C_PoleCaptureRadius)
  229. {
  230. NbBotsReachedPole += 1;
  231. TimeLastBotReachedPole = Now;
  232. UnspawnPlayer(Bot);
  233. }
  234. }
  235. }
  236. }
  237.  
  238. foreach(Player in Players)
  239. {
  240. declare CUIConfig UI;
  241. UI <=> UIManager.GetUI(Player);
  242.  
  243. // Frenzy
  244. declare Integer CurrentShotNb for Player;
  245. declare Integer CurrentHitStreak for Player;
  246. declare Integer LatestFrenzyTime for Player;
  247.  
  248. if(CurrentShotNb == CurrentHitStreak)
  249. {
  250. if(LatestFrenzyTime + C_FrenzyDuration < Now && CurrentHitStreak >= C_FrenzyThreshold)
  251. {
  252. LatestFrenzyTime = Now;
  253. }
  254. }
  255. else // Missed shot -> reset combo
  256. {
  257. CurrentHitStreak = 0;
  258. CurrentShotNb = 0;
  259. }
  260.  
  261.  
  262. if(LatestFrenzyTime < Now && Now < LatestFrenzyTime + C_FrenzyDuration)
  263. {
  264. CurrentHitStreak = 0;
  265. CurrentShotNb = 0;
  266. UI.StatusMessage = "FRENZY";
  267.  
  268. Player.AmmoGain = 1. * C_FrenzyAmmoGainMultiplier;
  269. }
  270. else
  271. {
  272. Player.AmmoGain = 1. * C_BaseAmmoGainMultiplier;
  273. }
  274.  
  275. // Informations o the bottom right of the screen
  276. UI.ManialinkPage = """
  277. <frame posn="157 -75 0">
  278. <label posn="0 0 1" halign="right" style="TextButtonNav" text="{{{_("Current Streak")}}}: {{{ CurrentHitStreak }}}" />
  279. </frame>
  280. <frame posn="157 -80 0">
  281. <label posn="0 0 1" halign="right" style="TextButtonNav" text="{{{_("Current Difficulty")}}}: {{{ Difficulty }}}" />
  282. </frame>
  283. <frame posn="157 -85 0">
  284. <label posn="0 0 1" halign="right" style="TextButtonNav" text="{{{_("Bots Reached Pole")}}}: {{{ NbBotsReachedPole }}}" />
  285. </frame>
  286. """;
  287. }
  288.  
  289. // Spawn a wave of bot on the beginning of each path
  290. if(BotPlayers.count < MaximumBotsNb && Now > NextBotSpawnTime)
  291. {
  292. foreach(Spawn in BotPaths)
  293. {
  294. for(I, 1, C_NbBotsPerWave)
  295. {
  296. // One would generally use (Spawn.Clan + 1) to define the clan of the bot
  297. // (unless the Spawn is neutral, which mean Spawn.Clan is 2 whereas the bot's clan needs to be 0)
  298. // In Horde we want all the bots on one side and all players on the other
  299. declare BotClan = 3-C_PlayerClan;
  300.  
  301. // We want a constant distance between the bots of a wave
  302. declare TimeDelta = MathLib::FloorInteger(C_BotsSpawnDeltaTime/C_Levels_SpeedPower[Difficulty]);
  303. SpawnBotPlayer(BotClan, C_BotArmor + BotsArmorBonus, Spawn, Now + (I-1)*TimeDelta, Difficulty);
  304. }
  305. }
  306.  
  307. if(Difficulty < C_MaxDifficulty)
  308. {
  309. Difficulty += 1;
  310. }
  311. else
  312. {
  313. BotsArmorBonus += 100;
  314. }
  315.  
  316. // Insane mode = on spawn en continu
  317. if(NbWavesSpawned >= C_NbWavesBeforeInsaneMode)
  318. {
  319. NextBotSpawnTime = Now + C_NbBotsPerWave*C_BotsSpawnDeltaTime;
  320. }
  321. else
  322. {
  323. NextBotSpawnTime = Now + C_BotsWavesSpawnDeltaTime;
  324. }
  325.  
  326. if(NbWavesSpawned != 0 && Difficulty < C_MaxDifficulty)
  327. {
  328. Difficulty += 1;
  329. LastDifficultyLevelUp = Now;
  330. }
  331.  
  332. LatestBotSpawnTime = Now;
  333. NbWavesSpawned += 1;
  334. }
  335.  
  336. if(NbWavesSpawned > C_NbWavesBeforeInsaneMode)
  337. {
  338. UIManager.UIAll.BigMessage = "INSANE MODE";
  339. }
  340. else if(Now >= LatestBotSpawnTime && Now <= LatestBotSpawnTime + 3000)
  341. {
  342. UIManager.UIAll.BigMessage = "New wave incoming !";
  343. }
  344. }
  345.  
  346. foreach(Player in Players)
  347. {
  348. declare CUIConfig UI;
  349. UI <=> UIManager.GetUI(Player);
  350.  
  351. UI.StatusMessage = "";
  352. UI.BigMessage = "";
  353. }
  354.  
  355. declare Score = TimeLastBotReachedPole - StartTime;
  356. return Score;
  357. }
  358.  
  359. main()
  360. {
  361. UseClans = True;
  362. UseAllies = True;
  363. DbgEnableNavMesh = True;
  364.  
  365. while (!ServerShutdownRequested)
  366. {
  367. ModelId = ItemList_Add("Characters/OrganicSmall.Item.gbx");
  368.  
  369. Mode::LoadMap();
  370.  
  371. SM::SetupDefaultVisibility();
  372.  
  373. // Game start
  374. sleep(3000);
  375. declare Score = 0;
  376. MatchEndRequested = False;
  377. Score = DoTry();
  378.  
  379. // Game over
  380. UnspawnEveryone();
  381. // Display score (and "medal")
  382. declare EndRoundTime = Now;
  383. while(Now - EndRoundTime <= 3000)
  384. {
  385. yield;
  386. CheckRecords(Score);
  387. }
  388.  
  389. ResetUI();
  390. log("Bots unspawned you can leave without CTD");
  391. sleep(5000);
  392. MatchEndRequested = True;
  393.  
  394. Mode::UnloadMap();
  395. }
  396. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement