Einen Rcon befehl erstellen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Einen Rcon befehl erstellen

      In diesem Tutorial werde ich euch zeigen wir ihr selbst herausfindet wie man einen Rcon Befehl erstellt und diesem eine Aufgabe zuordnet.
      Ich werde dieses Tuturial nach dem Prinzip Learning by Doing aufziehen und euch erst eine Aufgabe stellen,dann die Haupthilfen ohne Bsp geben
      und dann einmal mit. Am Ende werde ich noch einmal einen neuen Befehl hinzufügen welcher auf das Tutorial "Erste Schritte" beruht und Aip genannt wird.
      Bei Fragen zu C++ Kenntnissen schaut euch hier durch (sehr gutes nachschlagewerk highscore.de/cpp/einfuehrung/index.html

      Aufgabe:
      Versucht einen Rcon Befehl zu erstellen,diesem eine Aufgabe zu überteilen wo man schneller schießt (sogenanntes Aip).

      Wenn ihr nun nicht weiterkommt hier eine allgemeine Erklärung was ihr zuerst tun solltet um das Wissen zu erlangen einen Befehl zu erstellen
      Hilfe Nr.1
      Spoiler anzeigen
      Ein Rconbefehl ist eine Variable der einen Wert zugeteilt wird (bsp: sv_tournament_mode 1= an 0= aus)
      Ihr schaut euch zuerst einen rcon Befehl an den ihr schon kennt und wo ihr wisst wie er funktioniert. (Am besten einen einfachen)
      Nun schaut ihr euch zuerst dass an wo der Befehl erstellt wird und erst danach wie dem Befehl/Variable eine Aufgabe zugeteilt wird.
      Dateien die ihr nachschauen solltet sind: Gamecontext.cpp & config_variables.h
      Versucht euch zu überlegen welcher rcon befehl recht einfach aufgebaut ist und sucht dann nach diesem.


      Wenn ihr weitere Hilfe braucht kommt hier eine Erklärung was ein Rcon Befehl macht(wie er aufgebaut ist):
      Hilfe Nr.2
      Spoiler anzeigen
      Nun schaut ihr euch Gamecontext.cpp und Gamecontext.h an
      und sucht nun den Befehl say und versucht herauszufinden wie dieser funktioniert nach Hilfe Nr.1
      Erklärung:
      Spoiler anzeigen

      Gamecontext.h Zeile 54
      [cpp]static void ConSay(IConsole::IResult *pResult, void *pUserData); // Hier werden die Variablen angelegt
      [/cpp]

      Gamecontext.cpp Zeile 1327
      [cpp]Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "Say in chat"); //RconBefehl wird erstellt. Say ist der Befehl,mit dem die Variable aufgerufen wird und r ist der Parameter Typ(rest vom string)
      // Bekommt sie einen Wert greift sie auf ConSay zu(Es ist eine Funktion)[/cpp]

      Gamecontext.cpp Zeile 1028 - 1033
      [cpp]void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData) //Funktions wird gestartet | (Hier werden die Parameter angegeben)
      {
      CGameContext *pSelf = (CGameContext *)pUserData; //Ein neuer player wird erstellt, der die daten von pUserData übernimmt.
      pSelf->SendChat(-1, CGameContext::CHAT_ALL, pResult->GetString(0)); //Eingegeben Text wird gesendet via Funktion SendChat()
      }
      [/cpp]



      Lösung + Kommentare/Erklärungen der Aip Befehl(schneller schießen)
      Spoiler anzeigen



      Am Anfang solltet ihr den Befehl erstellen dies macht ihr in gamecontext.cpp
      Ihr ergänzt einfach ein Console()->Register(command,Datentyp int,serverlastig,späterer Funktionsname,this, "Was der Befehl macht")

      [cpp]void CGameContext::OnConsoleInit() //Hier erzeugt ihr eine neue Console()->Register Zeile
      Console()->Register("force_vote", "ss?r", CFGFLAG_SERVER, ConForceVote, this, "Force a voting option");
      Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "Clears the voting options");
      Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "Force a vote to yes/no");
      Console()->Register("aip", "i", CFGFLAG_SERVER, Conaip, this, "Activate fast shoots"); // Hier wird der Rcon Befehl angelegt
      // command,Datentyp int,serverlastig,Conaip ist die Funktion welche der int wert übermittelt wird(gut so Botox?)
      [/cpp]
      Nun als nächstes erstellen wir die die Funktion Conaip in gamecontext.cpp und gamecontext.h
      gamcontext.h L.62:
      Eine Zeile ergänzen mit dem Funktionsnamen (Conaip)

      [cpp]static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData);
      static void ConForceVote(IConsole::IResult *pResult, void *pUserData);
      static void ConClearVotes(IConsole::IResult *pResult, void *pUserData);
      static void ConVote(IConsole::IResult *pResult, void *pUserData);
      static void Conaip(IConsole::IResult *pResult, void *pUserData); //Hier werden die Variablen angelegt[/cpp]

      Nun für den weiteren Verlauf des Tutorial müssen wir eine Variable erstellen die einen wahrheitswert wieder gibts. Dies machen wir mit bool.
      Diesen bool fügen wir in player.h ein im public: bereicht (z.b irgwo zwischen 15 und 70)

      [cpp]

      bool m_aip; //bool gibt Wahrheitswert wieder d.h m_aip kann true or false sein.
      // wenn man m_aip nun woanders benutzen möchte muss man m_pPlayer->m_aip (bei character.cpp) benutzen bzw
      //m_apPlayers[ClientID] (bei gamecotext.cpp) wenn man etwas mit der ClientID der Players machen will.
      [/cpp]



      gamecontext.cpp
      Die Funktion selbst wird nun erstellt:

      [cpp]void CGameContext::Conaip(IConsole::IResult *pResult, void *pUserData)//Funktionsname: Conaip | *pResult: int Wert |
      //void *pUserData: übergibt Datentypen als Parameter
      {
      CGameContext *pSelf = (CGameContext *)pUserData; //gibt void *pUserData die Datentypen
      int ClientID = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1); //Client id wird der int Wert/wem wir aip geben



      if(!pSelf->m_apPlayers[ClientID]) // wenn es die ClientID nicht gibt
      return; //passiert nichts (Funktion wird ohne etwas gemacht zu haben beendet.

      char aBuf[128];//man kan 128 Zeichen lang schreiben
      if(!pSelf->m_apPlayers[ClientID]->m_aip) //wenn m_aip nicht aktiv ist des Clienten mit der ID
      {
      pSelf->m_apPlayers[ClientID]->m_aip = true; //dann wird aip angemacht bei dem CLienten mit der ID
      str_format(aBuf, sizeof(aBuf), "Activated aip", pSelf->Server()->ClientName(ClientID)); //Text/Ziel wird dem vorbereitet
      pSelf->SendChatTarget(ClientID, aBuf); // Text wird zum Ziel geschickt


      }
      else
      {
      pSelf->m_apPlayers[ClientID]->m_aip = false; //das Gegenteil wie oben
      str_format(aBuf, sizeof(aBuf), "Deactivated aip", pSelf->Server()->ClientName(ClientID)); //Gleiche nur anderer Text
      pSelf->SendChatTarget(ClientID, aBuf); // Text wird zum Ziel geschickt
      }
      }[/cpp]

      Nun haben wir die Funktion m_aip einen wahrheitswert gegeben. Wenn aip an ist ist m_aip = true wenn nicht m_aip = false
      Dies wird nun in character.cpp -> Funktion void CCharacter::FireWeapon() eingebaut

      [cpp]bool FullAuto = false;
      if(m_pPlayer->m_aip || m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE) //wenn m_aip an ist
      FullAuto = true; //wird autofire aktiviert

      [/cpp]

      In Zeile 2 wurde if(m_pPlayer->m_aip || hinzugefügt
      Nun werden wir Anderungen an den Letzen Zeilen der Funktion betätigen, wo wir Munition und Fastreload einstellen werden,

      [cpp]// Hier wird unendlich Ammo und schnelleres Schei0en geregelt

      if(!m_pPlayer->m_aip) //wenn m_aip == false
      {
      if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // wenn die aktive Waffe mehr Munition als 0 hat
      m_aWeapons[m_ActiveWeapon].m_Ammo--; // dann wird eine Munition abgezogen

      if(!m_ReloadTimer)//? wenn nachgeladen wird
      m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000; //muss " Aktivewaffeschussverzögerung
      //*Server()->TickSpeed() /1000 (normal)
      //gewartet werden bis man wieder schießen kann
      }
      else if(m_pPlayer->m_aip) //wenn m_aip == true
      {
      if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // wenn die aktive Waffe mehr Munition als 0 hat
      m_aWeapons[m_ActiveWeapon].m_Ammo++; // dann wird eine Munition hinzugefügt(immer volle Munition)

      if(!m_ReloadTimer) ////? wenn nachgeladen wird
      m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 5000; //muss " Aktivewaffeschussverzögerung
      //*Server()->TickSpeed() /5000 (fastreload)
      //gewartet werden bis man wieder schießen kann
      }[/cpp]

      Nun alle Dateien abspeichern und kompilelieren und siehe da, wie haben einen funktionierenden aip Befehl eingebaut


      So das wars erstmal mit dem Tutorial ich hoffe es wird euch weiter helfen
      Bei gefundenden Fehlern bitte mitteilen damit ich diese verbessern kann.


      Greetz warkid

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von warkid ()

    • pixel schrieb:

      Wann verstehst du es eigentlich: Ein Tutorial ist eine Gebrauchsanleitung, keine Aufgabenstellung.


      Wann hat mir das denn schonmal jemand gesagt dass : Ein Tutorial ist eine Gebrauchsanleitung, keine Aufgabenstellung.
      Und du checkst auch nicht dass dies noch ein Tutorial wird nur mit einer zu 100% erfolgreicherem Lernsystem als das bloße Vorsagen oder meinst du Pixel etwa dass man durch Vorsagen bzw einer Gebrauchsanweisung
      schneller lernen kann. Wenn ich mit dem Begriff Tutorial ins schwarze getroffen habe tut es mir sehr leid :( das ist ein Wort falsch bestimmt habe weil dies ist ja so schlimm wie ein Weltuntergang.
      Außerdem habe ich unten geschrieben:
      Ich werde den letzten Schritt morgen erweitern d.h Ich werde Schritt für Schritt den Befehl Aip einbauen und
      detailliert erklären wie ich dies mache. Dies wäre dann auch die Lösung der Aufgabe.

      Da wirst du dann deine Gebrauchsanweisung finden!
      Für die Leute die nicht wissen was Aip ist (für mich war es normal sry - dachte das wär ein Begriff den jeder von euch kennt) werde ich nochmal erklären was ich mir darunter vorstelle.
      Ich habe mich an Patafix und Botox ansage gehalten da die aufjedenfall mehr Erfahrung haben als du im Coden oder irre ich mich ?

      ps. Wie nennt man dieses Lernverfahren welches ich verwende ? Mir fällt kein Name ein.
    • mehr Erfahrung haben als du im Coden oder irre ich mich ?

      darum gehts grade nicht.

      Ich hab lediglich gesagt das du deine Scheiß Tutoprials am besten Umschreiben solltest, denn wann benutzt/sucht man ein Tutorial -- wenn man es nicht weiß, da bringt mir irgendein Rotz mit "Versuche es mit blabla, viellaucht auch so oder etwa so?" nicht viel.
      Wenn dir der Lernfortschritt des Einzelnen so am Herzen liegt, schreibt halt 'ne Schritt-für-Schritt-Anleitung mit Erklärung dies zur Lösung führt man.
      Bau deine Tutorials halt wie ein normaler Mensch auf:
      1. Öffne blabla.
      2. Suche di eZeile raus, die brauchen wir WEIL blabla...
      3. Ersetze durch, DENN...
      4. Anschließend bli bla blu
      und so weiter.

      Und bevor du mir jetzt noch Mose Texte vorhälst oder mich mit den 10 Geboten konfrontierst, änder einfach dein Tutorial, sehs als Verbesserungsvorschlag.
    • Hättest du von Anfang bis Ende gelesen könnten wir nun 4 unnötige Beiträge weniger hier haben ich zitiere wieder:
      Für heute wars das erstmal ich hoffe euch hat es gefallen und geholfen. Ich werde den letzten Schritt morgen erweitern d.h Ich werde Schritt für Schritt den Befehl Aip einbauen und
      detailliert erklären wie ich dies mache. Dies wäre dann auch die Lösung der Aufgabe.

      Der letzte schritt ist deine so viel versprechende Lernmethode.

      So und nun zu meiner Lernmethode:
      Ich habe mich nicht nur einfach so drangesetzt sondern auch überlegt wie man das Coden an sich durch dieses Tut am besten lernt, denn ich wollte vermeiden dass man einfach eine Lösung bekommt diese eintippt
      und am Ende ohne wirklich irgendetwas zu machen bzw selbst nachzudenken es geschafft hat == erfolgserlebnis ist gering
      Außerdem durch die vielen einzelnen Schritte bleibt es viel besser im Gedächtnis und man lernt einiges extra dazu. Selbst in einer Source klarzukommen was für spätere Aufgaben die man alleine machen muss
      sehr sehr wichtig ist. Außerdem gewinnt man so einen besseren Einblick in die Source und das Erfolgserlebnis ist erhöht.
      Zudem kann man eigentlich sagen dass Leute die meinen deine Lernmethode sei besser einfach den letzten Schritt machen.
      Wenn du denkst dass deine immernoch besser sei überdenke nun bitte das fast alle Bücher diese Methode im Grundgedanke machen. Sie stellen erst eine Aufgabe vorher wird das Thema mit einem anderen bsp erklärt (Hilfe Nr1 + Nr.2) und dann
      wird die Lösung preisgegeben.
      Meiner Meinung wird so der größte Lernfortschritt erziehlt.

      Patafix schrieb:

      @warkid: So in etwa habe ich mir das auch gedacht, ein Ziel geben und den Weg dahin bestmöglich beschreiben und kommentieren, vlt. noch Grafiken zur erläuterung hinzufügen :)
      Das hab ich in dem Tutorial bereits versucht ;)
    • onkelz eben die habe ich nicht - Aip zu erstellen sollte nciht ganz so schwer sein dachte ich mir und habe mich deshalb drangesetzt und ein Tutorial geschrieben.
      Aber ob Ahnung oder nicht die Lernmethode ist hammer =)

      Ich bezeichne mich selbst als Anfänger also denke ich wohl nicht das ich Ahnung habe. Vorallem mit Trunk nicht da ich bisjetzt nur based on DDRace stable gecodet habe.
      Ich bin ein Anfänger versuche dennoch zu helfen vorallem da ich weiß wo ein Anfänger Probleme haben ^^ (z.B hab ich grad ein Problem Aip hinzukriegen und versuche nun schon seit ner weile
      herauszufinden wie ich Aip hinkrieg bzw wie ich von gamecontext zu Character (FireWeapon) komme... )
    • Dann forder einfach Hilfe :D

      Zum tutorial "Ich werde euch zeigen, wie ihr selbst herausfindet...", da kann schonmal was nicht stimmen, da hat pixel recht :)
      Das tutorial sollte den weg zeigen, jedoch so gut erklärt, dass man es nachvollziehen kann, oder so aufgebaut, dass du den schritt vorgibst und der Nutzer sich überlegt, wie er diesen verwirklicht, schafft er das nicht, kann er sich immer noch die hilfe im spoiler anschauen ;)
      Einfach zu sagen: Hier Ziel, Hier Tipps, reicht leider nicht für ein tutorial sry
    • Ja das hätte ich machen müssen. Ich habe mich mit dem Aip Befehl überschätzt selbst zu machen. Dies habe ich selbst schon einmal gemacht jedoch Stable und einiges vergessen,
      dennoch dachte ich ich krieg das schon hin und gestern Nacht hatte ich auch einen guten "run" jedoch wurde ich müde und somit konnte ich den wichtigsten Teil am Tutorial nicht beenden.
      Ich werde heute aufjedenfall noch herausfinden wie man den Aip Befehl erstellt (Habe einen einzigen Fehler der beseitigt werden muss)
      und dann werde ich das Tutorial editieren und die Lösung schritt für schritt ergänzen,kommentieren und anchvollziehbar machen.
      Dennoch ist das Lernsystem ein bewehrtes welches auch viele Bücher benutzen. Ich werde es dennoch noch einmal gründlich überlegen und verbessern und auf die Kritiken eingehen.

      greetz warkid

      ps. auch du hast laut deinem Thread die letzten Codezeilen überlesen dass das Tutorial noch nicht ganz fertig ist (der wichtigste Teil fehlt)
      wenn ich es bis 20 uhr nicht allein gepackt habe werde ich Hilfe im Forum suchen bei meinem Problem.
    • Das wird einfach immer schlimmer...
      Ein Befehl ist KEINE Variable, desweiteren ist "r", welches als zweiter Parameter der Funktion Console()->Register() übergeben wird, ein Typspezifizierer. Dieser gibt den Typ des Übergabeparamters an Xter stelle nach dem Befehl an.

      Quellcode

      1. if(Command == 'r') // rest of the string
      2. break;
      3. else if(Command == 'i') // validate int
      4. pStr = str_skip_to_whitespace(pStr);
      5. else if(Command == 'f') // validate float
      6. pStr = str_skip_to_whitespace(pStr);
      7. else if(Command == 's') // validate string
      8. pStr = str_skip_to_whitespace(pStr);

      Auszug aus src/engine/shared/console.cpp


      // Playerselbst(also der der Say benutzt) wird zu pUserData (2. Parameter)
      CGameContext *pSelf = (CGameContext *)pUserData;

      Sag mal gehts noch? pSelf ist ein Pointer vom Datentyp CGameContext, und pUserData wird als CGameContext Pointer gecastet um keine Kompilerfehler zu erzeugen aber trotzdem verschieden Datentypen als Parameter zu übergeben.
      Ziemlich kompliziert für einen Anfänger und auch schwer zu erklären in einem Satz. Mit diesen "Tutorials" werden immer mehr Noobs geschaffen die eine komplett falsche Ahnung haben und bei anderen Angeben wie cool sie sind, weil sie STRG+C und STRG+V drücken können und dabei noch mit der Maustaste 1 klicken...

      Nehmt es mir nicht übel, aber ich muss echt kotzen nach diesem "Tutorial".
      Meine persönliche Empfehlung an euch: youtube.com/JuliensBlog
    • So hab den Fehler nun herausgefunden und ein ordentliches Aip erschaffen! Werde mich über die Nacht ans Tutorial setzen und das Feedback verbessern.
      Ich muss mich entschuldigen wenn ich nicht jeden einzelnen Fachausdruck kenne Botox und ich danke dir für deine Kritik
      Recht hast du bestimmt mit deiner für erfahrende Coder geschriebene Erklärungen leider bringen diese wunderbaren Fachbegriffe für den Anfang nicht viel
      sondern verwirren den Neuling eher. Ich selbst kenne nicht alle Befehlsnamen und entschuldige mich dafür. Daher bitte ich eich Erfahrenen am Ende des Tutorials nochmal
      hinüberzuschauen und die Fehler aufzulisten. Ich versuche sie dann passend zu ergänzen/editieren.
    • mhm ja stimmt ich hab zu eifrig dran gesetzt mir gedacht ach komm kommentieren wir alles in der source und dann hab ich vergessen dass es hier im Forum nicht so schön gerade ist.
      was in der src so war: (_ = leerzeichen)
      ______//Kommentar 1
      ______//Kommentar 2
      was so im Forum
      ___//Kommentar 1
      _______________//Kommentar 2
    • Also ich habe gleich die lösung abgeschrieben, um es zu testen, und
      es kommt immer son error beim kompilieren!

      //Edit: hier das bild vom error im anhang!
      kann das ned anders einfügen >.<
      Bilder
      • Fail.PNG

        47,12 kB, 673×337, 150 mal angesehen
      Nice Dekote, dekolti, dkoltee, ACH was solls geile titten^^
    • Quellcode

      1. void CCharacter::FireWeapon()
      2. {
      3. bool FullAuto = false;
      4. if(m_pPlayer->m_aip || m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE) //wenn m_aip an ist
      5. FullAuto = true;
      6. if(m_ReloadTimer != 0)
      7. return;
      8. DoWeaponSwitch();
      9. vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
      10. bool FullAuto = false;
      11. if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE)
      12. FullAuto = true;
      13. // check if we gonna fire
      14. bool WillFire = false;
      15. if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
      16. WillFire = true;
      17. if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo)
      18. WillFire = true;
      19. if(!WillFire)
      20. return;
      21. // check for ammo
      22. if(!m_aWeapons[m_ActiveWeapon].m_Ammo)
      23. {
      24. // 125ms is a magical limit of how fast a human can click
      25. m_ReloadTimer = 125 * Server()->TickSpeed() / 1000;
      26. GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
      27. return;
      28. }
      29. vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;
      30. switch(m_ActiveWeapon)
      31. {
      32. case WEAPON_HAMMER:
      33. {
      34. // reset objects Hit
      35. m_NumObjectsHit = 0;
      36. GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
      37. CCharacter *apEnts[MAX_CLIENTS];
      38. int Hits = 0;
      39. int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts,
      40. MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
      41. for (int i = 0; i < Num; ++i)
      42. {
      43. CCharacter *pTarget = apEnts[i];
      44. if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL))
      45. continue;
      46. // set his velocity to fast upward (for now)
      47. if(length(pTarget->m_Pos-ProjStartPos) > 0.0f)
      48. GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f);
      49. else
      50. GameServer()->CreateHammerHit(ProjStartPos);
      51. vec2 Dir;
      52. if (length(pTarget->m_Pos - m_Pos) > 0.0f)
      53. Dir = normalize(pTarget->m_Pos - m_Pos);
      54. else
      55. Dir = vec2(0.f, -1.f);
      56. pTarget->TakeDamage(vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage,
      57. m_pPlayer->GetCID(), m_ActiveWeapon);
      58. Hits++;
      59. }
      60. // if we Hit anything, we have to wait for the reload
      61. if(Hits)
      62. m_ReloadTimer = Server()->TickSpeed()/3;
      63. } break;
      64. case WEAPON_GUN:
      65. {
      66. CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GUN,
      67. m_pPlayer->GetCID(),
      68. ProjStartPos,
      69. Direction,
      70. (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
      71. 1, 0, 0, -1, WEAPON_GUN);
      72. // pack the Projectile and send it to the client Directly
      73. CNetObj_Projectile p;
      74. pProj->FillInfo(&p);
      75. CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
      76. Msg.AddInt(1);
      77. for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
      78. Msg.AddInt(((int *)&p)[i]);
      79. Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
      80. GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE);
      81. } break;
      82. case WEAPON_SHOTGUN:
      83. {
      84. int ShotSpread = 2;
      85. CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
      86. Msg.AddInt(ShotSpread*2+1);
      87. for(int i = -ShotSpread; i <= ShotSpread; ++i)
      88. {
      89. float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
      90. float a = GetAngle(Direction);
      91. a += Spreading[i+2];
      92. float v = 1-(absolute(i)/(float)ShotSpread);
      93. float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v);
      94. CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN,
      95. m_pPlayer->GetCID(),
      96. ProjStartPos,
      97. vec2(cosf(a), sinf(a))*Speed,
      98. (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
      99. 1, 0, 0, -1, WEAPON_SHOTGUN);
      100. // pack the Projectile and send it to the client Directly
      101. CNetObj_Projectile p;
      102. pProj->FillInfo(&p);
      103. for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
      104. Msg.AddInt(((int *)&p)[i]);
      105. }
      106. Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());
      107. GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
      108. } break;
      109. case WEAPON_GRENADE:
      110. {
      111. CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GRENADE,
      112. m_pPlayer->GetCID(),
      113. ProjStartPos,
      114. Direction,
      115. (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
      116. 1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
      117. // pack the Projectile and send it to the client Directly
      118. CNetObj_Projectile p;
      119. pProj->FillInfo(&p);
      120. CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
      121. Msg.AddInt(1);
      122. for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
      123. Msg.AddInt(((int *)&p)[i]);
      124. Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
      125. GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
      126. } break;
      127. case WEAPON_RIFLE:
      128. {
      129. new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
      130. GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
      131. } break;
      132. case WEAPON_NINJA:
      133. {
      134. // reset Hit objects
      135. m_NumObjectsHit = 0;
      136. m_Ninja.m_ActivationDir = Direction;
      137. m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
      138. m_Ninja.m_OldVelAmount = length(m_Core.m_Vel);
      139. GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
      140. } break;
      141. }
      142. m_AttackTick = Server()->Tick();
      143. if(!m_pPlayer->m_aip) //wenn m_aip == false
      144. {
      145. if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // wenn die aktive Waffe mehr Munition als 0 hat
      146. m_aWeapons[m_ActiveWeapon].m_Ammo--; // dann wird eine Munition abgezogen
      147. if(!m_ReloadTimer)//? wenn nachgeladen wird
      148. m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000; //muss " Aktivewaffeschussverzögerung
      149. //*Server()->TickSpeed() /1000 (normal)
      150. //gewartet werden bis man wieder schießen kann
      151. }
      152. else if(m_pPlayer->m_aip) //wenn m_aip == true
      153. {
      154. if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // wenn die aktive Waffe mehr Munition als 0 hat
      155. m_aWeapons[m_ActiveWeapon].m_Ammo++; // dann wird eine Munition hinzugefügt(immer volle Munition)
      156. if(!m_ReloadTimer) ////? wenn nachgeladen wird
      157. m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 5000; //muss " Aktivewaffeschussverzögerung
      158. //*Server()->TickSpeed() /5000 (fastreload)
      159. //gewartet werden bis man wieder schießen kann
      160. }
      Alles anzeigen
      Nice Dekote, dekolti, dkoltee, ACH was solls geile titten^^