Advertisement
Guest User

Untitled

a guest
Jul 29th, 2014
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.90 KB | None | 0 0
  1. // Archer animations
  2.  
  3. #include "ArcherCommon.as"
  4. #include "FireParticle.as"
  5. #include "RunnerAnimCommon.as";
  6. #include "RunnerCommon.as";
  7.  
  8. const f32 config_offset = -4.0f;
  9. const string shiny_layer = "shiny bit";
  10.  
  11. void onInit( CSprite@ this )
  12. {
  13. LoadSprites( this );
  14. }
  15.  
  16. void LoadSprites( CSprite@ this )
  17. {
  18. string texname = this.getBlob().getSexNum() == 0 ?
  19. "Entities/Characters/Archer/ArcherMale.png" :
  20. "Entities/Characters/Archer/ArcherFemale.png";
  21. this.ReloadSprite( texname, this.getConsts().frameWidth, this.getConsts().frameHeight,
  22. this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  23. this.RemoveSpriteLayer("frontarm");
  24. CSpriteLayer@ frontarm = this.addSpriteLayer( "frontarm", texname , 32, 16, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  25.  
  26. if (frontarm !is null)
  27. {
  28. Animation@ animcharge = frontarm.addAnimation( "charge", 0, false );
  29. animcharge.AddFrame(16);
  30. animcharge.AddFrame(24);
  31. animcharge.AddFrame(32);
  32. Animation@ animshoot = frontarm.addAnimation( "fired", 0, false );
  33. animshoot.AddFrame(40);
  34. Animation@ animnoarrow = frontarm.addAnimation( "no_arrow", 0, false );
  35. animnoarrow.AddFrame(25);
  36. frontarm.SetOffset( Vec2f(-1.0f,5.0f+config_offset) );
  37. frontarm.SetAnimation("fired");
  38. frontarm.SetVisible(false);
  39. }
  40.  
  41. this.RemoveSpriteLayer("backarm");
  42. CSpriteLayer@ backarm = this.addSpriteLayer( "backarm", texname , 32, 16, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  43.  
  44. if (backarm !is null)
  45. {
  46. Animation@ anim = backarm.addAnimation( "default", 0, false );
  47. anim.AddFrame(17);
  48. backarm.SetOffset( Vec2f(-1.0f,5.0f+config_offset) );
  49. backarm.SetAnimation("default");
  50. backarm.SetVisible(false);
  51. }
  52.  
  53. this.RemoveSpriteLayer("held arrow");
  54. CSpriteLayer@ arrow = this.addSpriteLayer( "held arrow", "Arrow.png" , 16, 8, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  55.  
  56. if (arrow !is null)
  57. {
  58. Animation@ anim = arrow.addAnimation( "default", 0, false );
  59. anim.AddFrame(1); //normal
  60. anim.AddFrame(8); //fire
  61. anim.AddFrame(14); //bomb
  62. anim.AddFrame(9); //water
  63. arrow.SetOffset( Vec2f(-1.0f,5.0f+config_offset) );
  64. arrow.SetAnimation("default");
  65. arrow.SetVisible(false);
  66. }
  67.  
  68. //quiver
  69. this.RemoveSpriteLayer("quiver");
  70. CSpriteLayer@ quiver = this.addSpriteLayer( "quiver", texname , 16, 16, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  71.  
  72. if (quiver !is null)
  73. {
  74. Animation@ anim = quiver.addAnimation( "default", 0, false );
  75. anim.AddFrame(67);
  76. anim.AddFrame(66);
  77. quiver.SetOffset( Vec2f(-10.0f,2.0f+config_offset) );
  78. quiver.SetRelativeZ(-0.1f);
  79. }
  80.  
  81. //grapple
  82. this.RemoveSpriteLayer("hook");
  83. CSpriteLayer@ hook = this.addSpriteLayer( "hook", texname , 16, 8, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  84.  
  85. if (hook !is null)
  86. {
  87. Animation@ anim = hook.addAnimation( "default", 0, false );
  88. anim.AddFrame(178);
  89. hook.SetRelativeZ(2.0f);
  90. hook.SetVisible(false);
  91. }
  92.  
  93. this.RemoveSpriteLayer("rope");
  94. CSpriteLayer@ rope = this.addSpriteLayer( "rope", texname , 32, 8, this.getBlob().getTeamNum(), this.getBlob().getSkinNum() );
  95.  
  96. if (rope !is null)
  97. {
  98. Animation@ anim = rope.addAnimation( "default", 0, false );
  99. anim.AddFrame(81);
  100. rope.SetRelativeZ(-1.5f);
  101. rope.SetVisible(false);
  102. }
  103.  
  104. // add shiny
  105. this.RemoveSpriteLayer(shiny_layer);
  106. CSpriteLayer@ shiny = this.addSpriteLayer( shiny_layer, "AnimeShiny.png", 16, 16 );
  107.  
  108. if (shiny !is null)
  109. {
  110. Animation@ anim = shiny.addAnimation( "default", 2, true );
  111. int[] frames = {0,1,2,3};
  112. anim.AddFrames(frames);
  113. shiny.SetVisible(false);
  114. shiny.SetRelativeZ(8.0f);
  115. }
  116. }
  117.  
  118. void setArmValues(CSpriteLayer@ arm, bool visible, f32 angle, f32 relativeZ, string anim, Vec2f around, Vec2f offset)
  119. {
  120. if (arm !is null)
  121. {
  122. arm.SetVisible(visible);
  123.  
  124. if(visible)
  125. {
  126. if (!arm.isAnimation(anim)) {
  127. arm.SetAnimation(anim);
  128. }
  129.  
  130. arm.SetOffset(offset);
  131. arm.ResetTransform( );
  132. arm.SetRelativeZ( relativeZ );
  133. arm.RotateBy( angle, around );
  134. }
  135. }
  136. }
  137.  
  138. // stuff for shiny - global cause is used by a couple functions in a tick
  139. bool needs_shiny = false;
  140. Vec2f shiny_offset;
  141. f32 shiny_angle = 0.0f;
  142.  
  143. void onTick( CSprite@ this )
  144. {
  145. // store some vars for ease and speed
  146. CBlob@ blob = this.getBlob();
  147.  
  148. if (blob.hasTag("dead"))
  149. {
  150. if (this.animation.name != "dead")
  151. {
  152. this.SetAnimation("dead");
  153. this.RemoveSpriteLayer("frontarm");
  154. this.RemoveSpriteLayer("backarm");
  155. this.RemoveSpriteLayer("held arrow");
  156. this.RemoveSpriteLayer(shiny_layer);
  157. }
  158.  
  159. doQuiverUpdate(this, false, true);
  160. doRopeUpdate(this, null, null);
  161.  
  162. Vec2f vel = blob.getVelocity();
  163.  
  164. if (vel.y < -1.0f) {
  165. this.SetFrameIndex( 0 );
  166. }
  167. else if (vel.y > 1.0f) {
  168. this.SetFrameIndex( 1 );
  169. }
  170. else {
  171. this.SetFrameIndex( 2 );
  172. }
  173.  
  174. return;
  175. }
  176.  
  177. ArcherInfo@ archer;
  178. if (!blob.get( "archerInfo", @archer )) {
  179. return;
  180. }
  181.  
  182. doRopeUpdate(this, blob, archer);
  183.  
  184. // animations
  185. const bool firing = IsFiring(blob);
  186. const bool left = blob.isKeyPressed(key_left);
  187. const bool right = blob.isKeyPressed(key_right);
  188. const bool up = blob.isKeyPressed(key_up);
  189. const bool down = blob.isKeyPressed(key_down);
  190. const bool inair = (!blob.isOnGround() && !blob.isOnLadder());
  191. bool legolas = archer.charge_state == ArcherParams::legolas_ready || archer.charge_state == ArcherParams::legolas_charging;
  192. needs_shiny = false;
  193. bool crouch = false;
  194.  
  195. const u8 knocked = blob.get_u8("knocked");
  196. Vec2f pos = blob.getPosition();
  197. Vec2f aimpos = blob.getAimPos();
  198. // get the angle of aiming with mouse
  199. Vec2f vec = aimpos - pos;
  200. f32 angle = vec.Angle();
  201.  
  202. if (knocked > 0)
  203. {
  204. if (inair) {
  205. this.SetAnimation("knocked_air");
  206. }
  207. else {
  208. this.SetAnimation("knocked");
  209. }
  210. }
  211. else if (blob.hasTag( "seated" ))
  212. {
  213. this.SetAnimation("default");
  214. }
  215. else if ( this.getBlob().get_s32("laserTimer") > 0 )
  216. {
  217. if (inair)
  218. {
  219. this.SetAnimation("shoot_jump");
  220. }
  221. else if ((left || right) ||
  222. (blob.isOnLadder() && (up || down) ) ) {
  223. this.SetAnimation("shoot_run");
  224. }
  225. else
  226. {
  227. this.SetAnimation("shoot");
  228. }
  229. }
  230. else if (inair)
  231. {
  232. RunnerMoveVars@ moveVars;
  233. if (!blob.get( "moveVars", @moveVars )) {
  234. return;
  235. }
  236. Vec2f vel = blob.getVelocity();
  237. f32 vy = vel.y;
  238. if (vy < -0.0f && moveVars.walljumped)
  239. {
  240. this.SetAnimation("run");
  241. }
  242. else
  243. {
  244. this.SetAnimation("fall");
  245. this.animation.timer = 0;
  246.  
  247. if (vy < -1.5 ) {
  248. this.animation.frame = 0;
  249. }
  250. else if (vy > 1.5 ) {
  251. this.animation.frame = 2;
  252. }
  253. else {
  254. this.animation.frame = 1;
  255. }
  256. }
  257. }
  258. else if ((left || right) ||
  259. (blob.isOnLadder() && (up || down) ) ) {
  260. this.SetAnimation("run");
  261. }
  262. else
  263. {
  264. if(down && this.isAnimationEnded())
  265. crouch = true;
  266.  
  267. int direction;
  268.  
  269. if ((angle > 330 && angle < 361) || (angle > -1 && angle < 30) ||
  270. (angle > 150 && angle < 210)) {
  271. direction = 0;
  272. }
  273. else if (aimpos.y < pos.y) {
  274. direction = -1;
  275. }
  276. else {
  277. direction = 1;
  278. }
  279.  
  280. defaultIdleAnim(this, blob, direction);
  281. }
  282.  
  283. //arm anims
  284. Vec2f armOffset = Vec2f(-1.0f,4.0f+config_offset);
  285. const u8 arrowType = getArrowType( blob );
  286.  
  287. if (firing || legolas)
  288. {
  289. f32 armangle = -angle;
  290.  
  291. if (this.isFacingLeft()) {
  292. armangle = 180.0f-angle;
  293. }
  294.  
  295. while (armangle > 180.0f) {
  296. armangle -= 360.0f;
  297. }
  298.  
  299. while (armangle < -180.0f) {
  300. armangle += 360.0f;
  301. }
  302.  
  303. //Zero - Bow Sprite
  304. /*DrawBow( this, blob, archer, armangle, arrowType, armOffset );*/
  305. }
  306. else
  307. {
  308. setArmValues(this.getSpriteLayer( "frontarm" ),false,0.0f,0.1f,"fired",Vec2f(0,0), armOffset);
  309. setArmValues(this.getSpriteLayer( "backarm" ),false,0.0f,-0.1f,"default",Vec2f(0,0), armOffset);
  310. setArmValues(this.getSpriteLayer( "held arrow" ), false, 0.0f,0.5f,"default",Vec2f(0,0), armOffset);
  311. }
  312.  
  313. //set the shiny dot on the arrow
  314.  
  315. CSpriteLayer@ shiny = this.getSpriteLayer( shiny_layer );
  316. if(shiny !is null)
  317. {
  318. shiny.SetVisible(needs_shiny);
  319. if(needs_shiny)
  320. {
  321. shiny.RotateBy(10, Vec2f());
  322.  
  323. shiny_offset.RotateBy( this.isFacingLeft() ? shiny_angle : -shiny_angle);
  324. shiny.SetOffset(shiny_offset);
  325. }
  326. }
  327.  
  328. DrawBowEffects( this, blob, archer, arrowType );
  329.  
  330. //set the head anim
  331. if (knocked > 0 || crouch)
  332. {
  333. blob.Tag("dead head");
  334. }
  335. else if ( this.getBlob().get_s32("laserTimer") > 0 )
  336. {
  337. blob.Tag("attack head");
  338. blob.Untag("dead head");
  339. }
  340. else
  341. {
  342. blob.Untag("attack head");
  343. blob.Untag("dead head");
  344. }
  345.  
  346. CControls@ controls = this.getBlob().getControls();
  347. if ( controls is null )
  348. {
  349. return;
  350. }
  351.  
  352. Vec2f distanceToMouse = ( controls.getMouseWorldPos() - this.getBlob().getPosition() );
  353. Vec2f mirroredDistanceToMouse = Vec2f(-distanceToMouse.x, -distanceToMouse.y);
  354.  
  355. this.RemoveSpriteLayer("railgun");
  356. CSpriteLayer@ railgun = this.addSpriteLayer("railgun", "Railgun.png", 32, 16);
  357. railgun.SetVisible(false);
  358. if ( this.getBlob().isFacingLeft() && ( this.getBlob().get_s32("laserTimer") > 0 ) )
  359. {
  360. railgun.SetFacingLeft(true);
  361. railgun.SetOffset( Vec2f(4.0f,1.0f) );
  362. railgun.RotateBy( -mirroredDistanceToMouse.getAngle(), Vec2f(0.0f,0.0f) );
  363. }
  364. else if ( this.getBlob().get_s32("laserTimer") > 0 )
  365. {
  366. railgun.SetFacingLeft(false);
  367. railgun.SetOffset( Vec2f(4.0f,1.0f) );
  368. railgun.RotateBy( -distanceToMouse.getAngle(), Vec2f(0.0f,0.0f) );
  369. }
  370. railgun.SetRelativeZ(200.0f);
  371.  
  372. if ( this.getBlob().get_s32("laserTimer") > 0 )
  373. {
  374. railgun.SetVisible(true);
  375. }
  376. else
  377. {
  378. railgun.SetVisible(false);
  379. }
  380. }
  381.  
  382. void DrawBow( CSprite@ this, CBlob@ blob, ArcherInfo@ archer, f32 armangle, const u8 arrowType, Vec2f armOffset )
  383. {
  384. f32 sign = (this.isFacingLeft()?1.0f:-1.0f);
  385. CSpriteLayer@ frontarm = this.getSpriteLayer( "frontarm" );
  386. CSpriteLayer@ arrow = this.getSpriteLayer( "held arrow" );
  387.  
  388. if (!archer.has_arrow || archer.charge_state == ArcherParams::no_arrows || archer.charge_state == ArcherParams::legolas_charging)
  389. {
  390. string animname = "no_arrow";
  391.  
  392. if (archer.charge_time == ArcherParams::ready_time)
  393. {
  394. animname = "fired";
  395. }
  396.  
  397. u16 frontframe = 0;
  398. f32 temp = Maths::Min( archer.charge_time, ArcherParams::ready_time );
  399. f32 ready_tween = temp / ArcherParams::ready_time;
  400. armangle = armangle * ready_tween;
  401. armOffset = Vec2f(-1.0f,4.0f+config_offset+2.0f*(1.0f-ready_tween));
  402. setArmValues(frontarm,true,armangle,0.1f,animname,Vec2f(-4.0f*sign,0.0f), armOffset );
  403. frontarm.animation.frame = frontframe;
  404.  
  405. setArmValues(arrow, false, 0, 0, "default", Vec2f(), Vec2f() );
  406. }
  407. else if (archer.charge_state == ArcherParams::readying)
  408. {
  409. u16 frontframe = 0;
  410. f32 temp = archer.charge_time;
  411. f32 ready_tween = temp / ArcherParams::ready_time;
  412. armangle = armangle * ready_tween;
  413. armOffset = Vec2f(-1.0f,4.0f+config_offset+2.0f*(1.0f-ready_tween));
  414. setArmValues(frontarm,true,armangle,0.1f,"charge",Vec2f(-4.0f*sign,0.0f), armOffset );
  415. frontarm.animation.frame = frontframe;
  416. f32 offsetChange = -5+ready_tween*5;
  417.  
  418. setArmValues(arrow, true, armangle, 0.05f, "default", Vec2f((-12.0f)*sign,0), armOffset+Vec2f(-8+offsetChange,0));
  419. arrow.animation.frame = arrowType;
  420. }
  421. else if (archer.charge_state != ArcherParams::fired || archer.charge_state == ArcherParams::legolas_ready)
  422. {
  423. u16 frontframe = Maths::Min((archer.charge_time/(ArcherParams::shoot_period_1+1)),2);
  424. setArmValues(frontarm,true,armangle,0.1f,"charge",Vec2f(-4.0f*sign,0.0f), armOffset);
  425. frontarm.animation.frame = frontframe;
  426.  
  427. const f32 arrowangle = (archer.charge_time > ArcherParams::shoot_period_2) ? armangle + -2.5f + float(XORRandom(500))/100.0f : armangle; // shiver arrow when fully charged
  428. const f32 frameOffset = 1.5f*float(frontframe);
  429.  
  430. setArmValues(arrow, true, arrowangle, 0.05f, "default", Vec2f(-(12.0f-frameOffset)*sign,0.0f), armOffset+Vec2f(-8+frameOffset,0));
  431. arrow.animation.frame = arrowType;
  432.  
  433. if(archer.charge_state == ArcherParams::legolas_ready)
  434. {
  435. needs_shiny = true;
  436. shiny_offset = Vec2f( -12.0f, 0.0f ); //TODO:
  437. shiny_angle = armangle;
  438. }
  439. }
  440. else
  441. {
  442. setArmValues(frontarm,true,armangle,0.1f,"fired",Vec2f(-4.0f*sign,0.0f), armOffset);
  443. setArmValues(arrow, false, 0.0f,0.5f,"default",Vec2f(0,0), armOffset);
  444. }
  445.  
  446. frontarm.SetRelativeZ(1.5f);
  447. setArmValues(this.getSpriteLayer( "backarm" ),true,armangle,-0.1f,"default",Vec2f(-4.0f*sign,0.0f), armOffset);
  448.  
  449. // fire arrow particles
  450.  
  451. if (arrowType == ArrowType::fire && getGameTime() % 6 == 0)
  452. {
  453. Vec2f offset = Vec2f(12.0f,0.0f);
  454.  
  455. if (this.isFacingLeft()) {
  456. offset.x = -offset.x;
  457. }
  458.  
  459. offset.RotateBy( armangle );
  460. makeFireParticle( frontarm.getWorldTranslation() + offset, 4 );
  461. }
  462. }
  463.  
  464. void DrawBowEffects( CSprite@ this, CBlob@ blob, ArcherInfo@ archer, const u8 arrowType )
  465. {
  466. // set fire light
  467.  
  468. if (arrowType == ArrowType::fire)
  469. {
  470. if (IsFiring(blob))
  471. {
  472. blob.SetLight(true);
  473. blob.SetLightRadius( blob.getRadius()*2.0f );
  474. }
  475. else
  476. {
  477. blob.SetLight(false);
  478. }
  479. }
  480.  
  481. //quiver
  482. bool has_arrows = blob.get_bool("has_arrow");
  483. doQuiverUpdate(this, has_arrows, true);
  484. }
  485.  
  486. bool IsFiring( CBlob@ blob )
  487. {
  488. return blob.isKeyPressed(key_action1);
  489. }
  490.  
  491. void doRopeUpdate(CSprite@ this, CBlob@ blob, ArcherInfo@ archer)
  492. {
  493. CSpriteLayer@ rope = this.getSpriteLayer("rope");
  494. CSpriteLayer@ hook = this.getSpriteLayer("hook");
  495.  
  496. bool visible = archer !is null && archer.grappling;
  497.  
  498. rope.SetVisible(visible);
  499. hook.SetVisible(visible);
  500. if(!visible)
  501. {
  502. return;
  503. }
  504.  
  505. Vec2f off = archer.grapple_pos - blob.getPosition();
  506.  
  507. f32 ropelen = Maths::Max(0.1f,off.Length() / 32.0f);
  508. if(ropelen > 200.0f)
  509. {
  510. rope.SetVisible(false);
  511. hook.SetVisible(false);
  512. return;
  513. }
  514.  
  515. rope.ResetTransform();
  516. rope.ScaleBy( Vec2f(ropelen,1.0f) );
  517.  
  518. rope.TranslateBy( Vec2f(ropelen*16.0f,0.0f) );
  519.  
  520. rope.RotateBy( -off.Angle() , Vec2f());
  521.  
  522. hook.ResetTransform();
  523. if(archer.grapple_id == 0xffff) //still in air
  524. {
  525. archer.cache_angle = -archer.grapple_vel.Angle();
  526. }
  527. hook.RotateBy( archer.cache_angle , Vec2f());
  528.  
  529. hook.TranslateBy( off );
  530. hook.SetFacingLeft(false);
  531.  
  532. //GUI::DrawLine(blob.getPosition(), archer.grapple_pos, SColor(255,255,255,255));
  533. }
  534.  
  535. void doQuiverUpdate(CSprite@ this, bool has_arrows, bool quiver)
  536. {
  537. CSpriteLayer@ quiverLayer = this.getSpriteLayer( "quiver" );
  538.  
  539. if (quiverLayer !is null)
  540. {
  541. if (quiver)
  542. {
  543. quiverLayer.SetVisible(true);
  544. f32 quiverangle = -45.0f;
  545.  
  546. if (this.isFacingLeft()) {
  547. quiverangle *= -1.0f;
  548. }
  549.  
  550. PixelOffset @po = getDriver().getPixelOffset( this.getFilename(), this.getFrame() );
  551.  
  552. bool down = (this.isAnimation("crouch") || this.isAnimation("dead"));
  553. bool easy = false;
  554. Vec2f off;
  555. if (po !is null)
  556. {
  557. easy = true;
  558. off.Set( this.getFrameWidth()/2, -this.getFrameHeight()/2 );
  559. off += this.getOffset();
  560. off += Vec2f( -po.x, po.y );
  561.  
  562.  
  563. f32 y = ( down ? 3.0f : 7.0f);
  564. f32 x = ( down ? 5.0f : 4.0f);
  565. off += Vec2f( x, y+config_offset );
  566. }
  567.  
  568. if (easy)
  569. {
  570. quiverLayer.SetOffset( off );
  571. }
  572.  
  573. quiverLayer.ResetTransform();
  574. quiverLayer.RotateBy(quiverangle, Vec2f(0.0f,0.0f));
  575.  
  576. if (has_arrows) {
  577. quiverLayer.animation.frame = 1;
  578. }
  579. else {
  580. quiverLayer.animation.frame = 0;
  581. }
  582. }
  583. else
  584. {
  585. quiverLayer.SetVisible(false);
  586. }
  587. }
  588. }
  589.  
  590. void onGib(CSprite@ this)
  591. {
  592. if (g_kidssafe) {
  593. return;
  594. }
  595.  
  596. CBlob@ blob = this.getBlob();
  597. Vec2f pos = blob.getPosition();
  598. Vec2f vel = blob.getVelocity();
  599. vel.y -= 3.0f;
  600. f32 hp = Maths::Min(Maths::Abs(blob.getHealth()),2.0f) + 1.0f;
  601. const u8 team = blob.getTeamNum();
  602. CParticle@ Body = makeGibParticle( "Entities/Characters/Archer/ArcherGibs.png", pos, vel + getRandomVelocity( 90, hp , 80 ), 0, 0, Vec2f (16,16), 2.0f, 20, "/BodyGibFall", team );
  603. CParticle@ Arm = makeGibParticle( "Entities/Characters/Archer/ArcherGibs.png", pos, vel + getRandomVelocity( 90, hp - 0.2 , 80 ), 1, 0, Vec2f (16,16), 2.0f, 20, "/BodyGibFall", team );
  604. CParticle@ Shield = makeGibParticle( "Entities/Characters/Archer/ArcherGibs.png", pos, vel + getRandomVelocity( 90, hp , 80 ), 2, 0, Vec2f (16,16), 2.0f, 0, "Sounds/material_drop.ogg", team );
  605. CParticle@ Sword = makeGibParticle( "Entities/Characters/Archer/ArcherGibs.png", pos, vel + getRandomVelocity( 90, hp + 1 , 80 ), 3, 0, Vec2f (16,16), 2.0f, 0, "Sounds/material_drop.ogg", team );
  606. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement