Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/AsteroidMining_HS17/src/modules/asteroidmining/AsteroidMinable.cc @ 11587

Last change on this file since 11587 was 11587, checked in by remartin, 6 years ago

Kleinere Probleme gelöst (HP, Position richtig setzen). Noch die Eigenkollision des Pickups verhindern und die Grundfunktionalität steht.

File size: 20.2 KB
Line 
1
2 /*   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Simon Miescher
26 *
27 */
28
29/*
30
31*
32*
33* An asteroid which can be destroyed. Some smaller asteroids are created and a pickup
34* spawns.
35*
36*
37*
38
39*/
40
41/*
42Veraenderungstagebuch
43++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44
45KNACKPUNKTE:
46o Der neu erscheinende Asteroid versucht, das Pickup aufzusammeln.
47--> Mathematisch genuegend Abstand?
48--> Kollisions-Ausnahme richtig, mit Hit-Methode oder so, auch bei Pickup anpassen?
49--> Den Fall im eigenen Pickup behandeln?
50--> Nur ein Pickup generieren, wenn die Groesse sowieso eins ist? -> Loest Kollisionsproblem nicht.
51
52
53OFFEN:
54o Add custom pickup 'resources'. Weird template stuff -> Problems setting 'size' and other properties? setNumber of Resources.
55o Explosion parts
56o custom HUD
57o asteroidField.lua anpassen, mit 'Mineraliendichten-Parameter'.
58
59HANDBUCH:
60o im Level-File includes/pickups.oxi importieren.
61o Bei der XML-Variante wird beim ersten Aufruf der Tick-Methode ein neuer Asteroid generiert,
62  damit die Groesse der Collision Shape korrekt initialisiert wird.
63
64Anpassungen Pickup-Zeug:
65o Pickup.h: Zugriffsänderung createSpawner
66o PickupSpawner.h: Zugriffsrechte setPickupTemplateName() und setMaxSpawnedItems()
67
68ERLEGT:
69o Rand() geht bis zu riesigen Nummern!
70o Pickupgenerierung: vgl. Anpassungen.
71o Dummes fisch-- statt fisch++ , Endlosschleife!
72o Dynamische Definition -> putStuff-Methode, Werte noch nicht durchgesickert.
73o Error-Nachricht: Einfach Argumente leer lassen.
74o Pickups: setMaxSpawned funktioniert nicht -> Bastelloesung: Auf 2 statt eins setzen, erstes wird wohl direkt zerstoert.
75o setHealth: Wird mit Max verwurstelt, war 0.
76o Position nicht gesetzt -> alles im Ursprung, Kollision -> fliegt davon.
77o nimmt zuviel Schaden. -> wird mit maxHealth verwurstelt -> einfach auch setzen.
78
79o Groessenabhaengige Collison shape: Umweg ueber zweiten Konstruktor.
80o Absturz beim Asteroidengenerieren: Health war auf 0 gesetzt! Wurde nur bei der xml-Variante definiert.
81
82NOTIZEN:
83o SUPER entspricht ueberladen, andere Argumente der Methode.
84
85*/
86
87
88#include "../../orxonox/worldentities/pawns/Pawn.h"
89#include "../../orxonox/worldentities/WorldEntity.h"
90
91#include "AsteroidMinable.h"
92
93#include <algorithm>
94
95#include "core/CoreIncludes.h"
96#include "core/GameMode.h"
97#include "core/XMLPort.h"
98#include "core/EventIncludes.h"
99#include "network/NetworkFunction.h"
100
101// #include "infos/PlayerInfo.h"
102// #include "controllers/Controller.h"
103// #include "gametypes/Gametype.h"
104// #include "graphics/ParticleSpawner.h"
105// #include "worldentities/ExplosionChunk.h"
106// #include "worldentities/ExplosionPart.h"
107
108// #include "core/object/ObjectListIterator.h"
109// #include "controllers/FormationController.h"
110
111#include "../pickup/items/HealthPickup.h"
112#include "../pickup/PickupSpawner.h"
113#include "../pickup/Pickup.h"
114//#include "../pickup/pickup ..... pickupable
115#include "../objects/collisionshapes/SphereCollisionShape.h"
116#include "../../orxonox/graphics/Model.h"
117
118
119
120
121
122
123namespace orxonox
124{
125    RegisterClass(AsteroidMinable);
126
127
128    // This constructor is for XML access only.
129    AsteroidMinable::AsteroidMinable(Context* context) : Pawn(context){
130
131        // Da auch noetig? Wegen set in XML-Code?
132        RegisterObject(AsteroidMinable);
133
134        this->context = context;
135        this->initialised = false;
136
137        //Noetig, damit nicht sofort zerstoert?
138        this->setCollisionType(WorldEntity::CollisionType::Dynamic);
139
140        // Old from Pawn
141        this->registerVariables();
142
143        orxout() << "AsteroidMining:: Pseudo-Konstruktor passiert!" << endl;
144
145    }
146
147    // Call this one from other C-files. Takes arguments.
148    AsteroidMinable::AsteroidMinable(Context* c, float size, Vector3 position) : Pawn(c){
149
150        RegisterObject(AsteroidMinable);
151
152        // Old stuff from pawn
153        this->setRadarObjectColour(ColourValue(1.0f, 1.0f, 0.0f, 1.0f));
154        this->setRadarObjectShape(RadarViewable::Shape::Dot);
155        this->setCollisionType(WorldEntity::CollisionType::Dynamic);
156
157        this->enableCollisionCallback();
158
159        // Default Values
160        this->generateSmaller = true; 
161        //this->setHealth(50);
162        this->context = c;
163        this->size = size; // customSize
164        this->health_ = 15*size;// capped at 200 in pawn or smth?
165        this->maxHealth_ = this->health_;
166        this->setPosition(position);
167        //this->roll = rand()*5; //etwas Drehung. richtige Variable
168
169        // // Fliegt davon, irgendwieso. Dies scheint auch nicht zu nuetzen.
170        // this->setVelocity(Vector3(0,0,0));
171
172
173
174        // Add Model    //<Model position="0,-40,40" yaw="90" pitch="-90" roll="0" scale="4" mesh="ast6.mesh" />
175        Model* hull = new Model(this->context);
176        // random one of the 6 shapes
177        char meshThingy[] = "";
178        sprintf(meshThingy, "ast%.0f.mesh", (round((5*(double)rand()/(double)RAND_MAX))+1)); //    sprintf(str, "Value of Pi = %f", M_PI);
179        hull->setMeshSource(meshThingy);
180        hull->setScale(this->size);
181        this->attach(hull);
182
183        // Collision shape
184        SphereCollisionShape* cs = new SphereCollisionShape(this->context);
185        cs->setRadius((this->size)*2); //OFFEN: Feinabstimmung der Radien. 2.5 in AsteroidField.lua
186        this->attachCollisionShape(cs); 
187
188        // Old from Pawn
189        this->registerVariables();
190
191        this->initialised=true; 
192
193        orxout() << "AsteroidMining:: Initialisierung Zweitkonstruktor abgeschlosssssen." << endl;
194
195    }
196
197    AsteroidMinable::~AsteroidMinable(){
198
199    }
200
201    void AsteroidMinable::putStuff(){
202
203        // Just create a new asteroid to avoid Collision shape scale problems etc.
204        AsteroidMinable* reborn = new AsteroidMinable(this->context, this->size, this->getPosition());
205        reborn->toggleShattering(true); // mainly here to avoid 'unused' warning.
206        this->~AsteroidMinable(); // seems dangerous. Necessary for efficiency?
207
208    }
209
210    void AsteroidMinable::XMLPort(Element& xmlelement, XMLPort::Mode mode)
211    {
212        SUPER(AsteroidMinable, XMLPort, xmlelement, mode);
213        //        XMLPortParam(PickupSpawner, "pickup", setPickupTemplateName, getPickupTemplateName, xmlelement, mode);
214        XMLPortParam(AsteroidMinable, "size", setSize, getSize, xmlelement, mode);
215
216    }
217
218    void AsteroidMinable::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
219    {
220        SUPER(AsteroidMinable, XMLEventPort, xmlelement, mode);
221
222        XMLPortEventState(AsteroidMinable, BaseObject, "vulnerability", setVulnerable, xmlelement, mode);
223    }
224
225    void AsteroidMinable::registerVariables()
226    {
227        // registerVariable(this->bAlive_,            VariableDirection::ToClient);
228        // registerVariable(this->bVulnerable_,       VariableDirection::ToClient);
229        // registerVariable(this->health_,            VariableDirection::ToClient);
230        // registerVariable(this->maxHealth_,         VariableDirection::ToClient);
231
232        registerVariable(this->size, VariableDirection::ToClient);
233        registerVariable(this->generateSmaller, VariableDirection::ToClient);
234
235        registerVariable(this->initialised, VariableDirection::ToClient);
236        //registerVariable(this->context, VariableDirection::ToClient); // can't link that since it's a context
237
238
239            //         float size;
240            // bool generateSmaller;
241            // bool initialised;
242
243            // Context* context;
244    }
245
246    void AsteroidMinable::tick(float dt)
247    {
248        if(!(this->initialised)){this->putStuff();}
249
250        if(this->health_ <=0){this->death();}
251
252        // if(this->initialised){
253        //     // this->setVelocity(Vector3(0,0,0));  // Funktioniert, scheint aber unsinnig.
254        //     orxout() << "Flying at speed: " << this->getVelocity() << endl;
255        // }
256
257    }
258
259    void AsteroidMinable::setSize(float s){
260        this->size = s;
261    }
262
263    float AsteroidMinable::getSize(){
264        return this->size;
265    }
266
267    void AsteroidMinable::toggleShattering(bool b){
268        this->generateSmaller = b;
269    }
270
271
272    void AsteroidMinable::death() //ueberschreiben
273    {
274
275        orxout() << "AsteroidMinable::Death() aufgerufen." << endl;
276
277        // OFFEN: Sauber kapputten
278        // just copied other stuff:
279        // this->setHealth(1);
280        this->bAlive_ = false;
281        this->destroyLater();
282        this->setDestroyWhenPlayerLeft(false);
283        // pawn -> addExplosionPart
284        // this->goWithStyle();
285
286
287        // // Stuff that can be harvested.
288        // PickupSpawner* thingy = new PickupSpawner(this->context);
289
290        // // OFFEN: more precise size relation in custom resource pickup.
291        // char tname[] = ""; // can-t overwrite strings easily in C (strcat etc.)
292        // if(this->size <= 5){
293        //     strcat(tname, "smallmunitionpickup");
294        // }else if(this->size <= 20){
295        //     strcat(tname, "mediummunitionpickup");
296        // }else{
297        //     strcat(tname, "hugemunitionpickup");
298        // }
299        // thingy->setPickupTemplateName(tname);
300        // thingy->setPosition(this->getPosition());
301        // thingy->setMaxSpawnedItems(2); // The first somehow gets destroyed immediately.
302        // thingy->setRespawnTime(0.5f);
303
304        // orxout() << "AsteroidMining::Death(): Passed Pickup stuff!" << endl;
305
306
307        // Smaller Parts = 'Children'
308        if(this->generateSmaller){
309            this->spawnChildren();
310        }
311
312
313
314
315
316
317
318
319        orxout() << "Wieder retour in death() geschafft. " << endl;
320
321        // if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
322        // {
323        //     // Set bAlive_ to false and wait for destroyLater() to do the destruction
324        //     this->bAlive_ = false;
325        //     this->destroyLater();
326
327        //     this->setDestroyWhenPlayerLeft(false);
328
329        // }
330    }
331
332
333void AsteroidMinable::spawnChildren(){
334   
335    if (this->size <=1){return;} // Absicherung trivialer Fall
336
337
338
339    // Spawn smaller Children
340    int massRem = this->size-1; //some mass is lost
341    int num = round((massRem-1)*(double)rand() / (double)RAND_MAX)+1; // random number of children, at least one // Tweak towards bigger junks?
342    // num = 1; // zum Testen mal nur einen generieren.
343   
344    massRem = massRem-num;   
345    int extra = 0;
346
347
348    //orxout() << "Number of Children: " << num << endl;
349
350
351    for(int fisch=num; fisch>=1; --fisch){
352        // to distribute remaining mass
353
354        //orxout() << "AsteroidMining::spawnChildren(): Fisch-Variable: " << fisch << endl;
355
356        if(fisch==1){ 
357            extra = massRem;
358        }else{
359            extra = round(massRem*(double)rand() / (double)RAND_MAX);
360            massRem = massRem-extra;
361
362        }
363
364        //orxout() << "Mass chosen: " << extra+1 << endl;
365
366        //orxout() << "AsteroidMining::spawnChildren(): Inside for-loop." << endl;
367
368        //Spawn this child  Game crashes!
369        //AsteroidMinable* child = new AsteroidMinable(this->context);
370        int newMass = extra+1; 
371        AsteroidMinable* child = new AsteroidMinable(this->context, newMass, this->getPosition() + Vector3(fisch*newMass*2.5, 0, 0));
372        // if(!(child == nullptr)){//Errorgebastel
373
374        // Position zu spaet gesetzt? Tick nicht atomar -> falsche Groesse evtl?
375
376        // child->setSize(extra + 1);
377               
378        //     //OFFEN:Kollision der Kinder verhindern
379        //     //Relativ zu Elternteil automatisch?
380        //     //Typ position:rand()*Vektoriwas?
381        //     //pawn->getWorldPosition() + Vector3(30,0,-30);
382        // child->setPosition(this->getPosition() + Vector3(num*5, 0, 0));
383        // //child->setPosition(Vector3(0,0,0));
384
385        if(child == nullptr){
386            orxout(internal_error, context::pickups) << "Weird, can't create new AsteroidMinable." << endl;
387        }
388
389
390
391        //orxout() << "Done: Creating new Asteroid" << endl;
392
393        // }
394
395
396                //         Pawn* pawn = this->carrierToPawnHelper();
397                // if(pawn == nullptr) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
398                //     this->Pickupable::destroy();
399
400                // //Attach to pawn
401                // Drone* drone = new Drone(pawn->getContext()); // this is neccessary because the projectiles fired need a valid creator for the particlespawner (when colliding against something)
402                // drone->addTemplate(this->getDroneTemplate());
403
404
405    }
406    orxout() << "Leaving spawnChildren() method. " << endl;
407}
408
409
410    void AsteroidMinable::hit(Pawn* originator, const Vector3& force, const btCollisionShape* cs, float damage, float healthdamage, float shielddamage){
411
412        orxout() << "AsteroidMining::Hit(Variante 1) Dings aufgerufen. " << endl;
413
414        // Kollision mit anderem Asteroid oder Pickup (OFFEN: evtl. Spawner oder irgendwas?) verhindern. In diesem Fall einfach nichts tun.
415        // Wird staending aufgerufen -> Rechenleistung?
416        if(orxonox_cast<AsteroidMinable*>(originator) || orxonox_cast<Pickup*>(originator)){return;}
417        this->damage(damage, healthdamage, shielddamage, originator, cs);
418        this->setVelocity(this->getVelocity() + force);
419
420
421
422        // if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator))// && (!this->getController() || !this->getController()->getGodMode()) )
423        // {
424        //     this->damage(damage, healthdamage, shielddamage, originator, cs);
425        //     this->setVelocity(this->getVelocity() + force);
426        // }
427    }
428
429    void AsteroidMinable::hit(Pawn* originator, btManifoldPoint& contactpoint, const btCollisionShape* cs, float damage, float healthdamage, float shielddamage){
430
431        orxout() << "AsteroidMining::Hit(Variante 2) Dings aufgerufen. " << endl;
432        // Kollision mit anderem Asteroid oder Pickup (OFFEN: evtl. Spawner oder irgendwas?) verhindern. In diesem Fall einfach nichts tun.
433        // Wird staending aufgerufen -> Rechenleistung?
434        if(orxonox_cast<AsteroidMinable*>(originator) || orxonox_cast<Pickup*>(originator)){return;}
435
436        orxout() << "Schaden. HP: " << this->health_ << " Dmg: " << damage << " hDmg: " << healthdamage << " sDmg: " << shielddamage << endl;
437
438        this->damage(damage, healthdamage, shielddamage, originator, cs);
439
440
441
442
443        // if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator))// && (!this->getController() || !this->getController()->getGodMode()) )
444        // {
445        //     this->damage(damage, healthdamage, shielddamage, originator, cs);
446
447        //     //if ( this->getController() )
448        //     //    this->getController()->hit(originator, contactpoint, damage); // changed to damage, why shielddamage?
449        // }
450    }
451
452
453
454
455            // Cast-Test aus movableEntity():
456            // Pawn* victim = orxonox_cast<Pawn*>(otherObject);
457            // if (victim)
458
459
460
461
462//Pawn:
463    // void Pawn::hit(Pawn* originator, const Vector3& force, const btCollisionShape* cs, float damage, float healthdamage, float shielddamage)
464    // {
465    //     if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
466    //     {
467    //         this->damage(damage, healthdamage, shielddamage, originator, cs);
468    //         this->setVelocity(this->getVelocity() + force);
469    //     }
470    // }
471
472    // void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, const btCollisionShape* cs, float damage, float healthdamage, float shielddamage)
473    // {
474    //     if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
475    //     {
476    //         this->damage(damage, healthdamage, shielddamage, originator, cs);
477
478    //         if ( this->getController() )
479    //             this->getController()->hit(originator, contactpoint, damage); // changed to damage, why shielddamage?
480    //     }
481    // }
482
483
484
485
486            // /**
487            // @brief
488            //     Virtual function that gets called when this object collides with another.
489            // @param otherObject
490            //     The object this one has collided into.
491            // @param ownCollisionShape
492            //     The collision shape of the other object
493            // @param contactPoint
494            //     Contact point provided by Bullet. Holds more information and can me modified. See return value.
495            // @return
496            //     Returning false means that no modification to the contactPoint has been made. Return true otherwise!
497            // @note
498            //     Condition is that enableCollisionCallback() was called.
499            // */
500            // virtual inline bool collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint)
501            //     { return false; } /* With false, Bullet assumes no modification to the collision objects. */
502
503            // //! Enables the collidesAgainst(.) function. The object doesn't respond to collision otherwise!
504            // inline void enableCollisionCallback()
505            //     { this->bCollisionCallbackActive_ = true; this->collisionCallbackActivityChanged(); }
506
507
508
509            // //! Disables the collidesAgainst(.) function. @see enableCollisionCallback()
510            // inline void disableCollisionCallback()
511            //     { this->bCollisionCallbackActive_ = false; this->collisionCallbackActivityChanged(); }
512
513
514            // //! Tells whether there could be a collision callback via collidesAgainst(.)
515            // inline bool isCollisionCallbackActive() const
516            //     { return this->bCollisionCallbackActive_; }
517
518            // //! Enables or disables collision response (default is of course on)
519            // inline void setCollisionResponse(bool value)
520            //     { this->bCollisionResponseActive_ = value; this->collisionResponseActivityChanged(); }
521
522
523            // //! Tells whether there could be a collision response
524            // inline bool hasCollisionResponse()
525            //     { return this->bCollisionResponseActive_; }
526
527
528}
529
530
531
532
533
534/*
535    void DronePickup::changedUsed(void)
536    {
537        SUPER(DronePickup, changedUsed);
538
539        // If the pickup has transited to used.
540        if(this->isUsed())
541        {
542
543                Pawn* pawn = this->carrierToPawnHelper();
544                if(pawn == nullptr) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
545                    this->Pickupable::destroy();
546
547                //Attach to pawn
548                Drone* drone = new Drone(pawn->getContext()); // this is neccessary because the projectiles fired need a valid creator for the particlespawner (when colliding against something)
549                drone->addTemplate(this->getDroneTemplate());
550
551                Controller* controller = drone->getController();
552                DroneController* droneController = orxonox_cast<DroneController*>(controller);
553                if(droneController != nullptr)
554                {
555                    droneController->setOwner(pawn);
556                }
557
558                Vector3 spawnPosition = pawn->getWorldPosition() + Vector3(30,0,-30);
559                drone->setPosition(spawnPosition);
560
561                // The pickup has been used up.
562                this->setUsed(false);
563        }
564        else
565        {
566            // If either the pickup can only be used once or it is continuous and used up, it is destroyed upon setting it to unused.
567            if(this->isOnce() || (this->isContinuous() ))
568            {
569                this->Pickupable::destroy();
570            }
571        }
572    }
573*/
Note: See TracBrowser for help on using the repository browser.