Genesis3D Programming - Genesis3D University is your resource for Genesis3D Game development
Download Genesis3D v1.1
|
Programming | ||
http://Welcome.to/Genesis3D-University
Flame Thrower For GTest 1.1
By: David Bonolo Hi again. This is my third tutorial. I will show you how to make a flame thrower for GTest. This is somewhat what it looks like:
The code is basically just the Blaster code copied over, but modified. Let’s begin. All code changes are done in Yellow.
Go to the FireBlaster function in Weapon.c. Add at the end, about line 1043 or so, add this large block of code: //================================================ // Flame_Control //================================================ geBoolean Flame_Control(GenVSI *VSI, void *PlayerData, float Time) {
geVec3d
In, Front, Back; Player = (GPlayer*)PlayerData; Player->Time += Time; Speed = Player->Time*3600.0f;
if (Speed > 4000.0f) geXForm3d_Copy(&Player->XForm, &DestXForm); geXForm3d_GetIn(&Player->XForm, &In); geVec3d_Scale(&In, Speed*Time, &In); geXForm3d_Translate(&DestXForm, In.X, In.Y, In.Z); geXForm3d_GetIn(&Player->XForm, &In); geVec3d_Scale(&In, 500.f, &Player->Velocity); Front = Player->XForm.Translation; Back = DestXForm.Translation; geXForm3d_Copy(&DestXForm, &Player->XForm); World = GenVSI_GetWorld(VSI);
assert(World); Data.VSI = VSI; Data.Player = Player;
if (geWorld_Collision(World, NULL, NULL, &Front, &Back, { Player->XForm.Translation = Collide.Impact;
geVec3d_AddScaled(&Player->XForm.Translation, if
(Collide.Model) GPlayer *Target; Target = (GPlayer*)geWorld_ModelGetUserData(Collide.Model);
if (Target && Target->Trigger && Target->ViewFlags
& } //if (VSI->Mode == MODE_Server) { if (Collide.Actor) { GPlayer *PlayerHit; PlayerHit = GenVSI_ActorToPlayer(VSI, Collide.Actor); if (PlayerHit && PlayerHit != Player->Owner)
DammagePlayer(VSI, Player, PlayerHit, 15, } else
RadiusDammage(VSI, Player, 10, BLASTER_POWER_RADIUS, }
GenVSI_SpawnFx(VSI, FX_EXPLODE2, &Player->XForm.Translation,
GenVSI_DestroyPlayer(VSI, PlayerData); }
if (Player->Time >= 0.40f) // Kill it after god only knows GenVSI_DestroyPlayer(VSI, PlayerData);
Player->VPos = Player->XForm.Translation;
return GE_TRUE; }
//=================================================== // FireFlame //=================================================== void FireFlame(GenVSI *VSI, void *PlayerData, float Time) { GPlayer *Weapon; geVec3d Up, In, Rt, Front, Back, Impact; GE_Collision Collision; geWorld *World; GPlayer *Player; CData Data;
Player = (GPlayer*)PlayerData; Weapon = GenVSI_SpawnPlayer(VSI, "Weapon_Flame");
if (!Weapon) { GenVSI_ConsolePrintf(VSI, "FireFlame: Failed to add player.\n"); return; }
// Setup the callbacks for this weapon Weapon->Control = Flame_Control; Weapon->Blocked = NULL; Weapon->Trigger = NULL; Weapon->Owner = Player; Weapon->Time = 0.0f; Weapon->PingTime = Player->PingTime;
geVec3d_Set(&Weapon->Mins, -10.0f, -10.0f, -10.0f); geVec3d_Set(&Weapon->Maxs, 10.0f, 10.0f, 10.0f);
Weapon->ControlIndex = 5;
Weapon->ViewFlags = (VIEW_TYPE_SPRITE | VIEW_TYPE_LIGHT); Weapon->ViewIndex = TEXTURE_INDEX_WEAPON2; Weapon->Scale = 3.5f; Weapon->FxFlags = FX_EXPLODE2; // Make some flames follow Weapon_Flame
Weapon->XForm = Player->XForm;
geVec3d_Add(&Weapon->XForm.Translation, &Player->GunOffset,
geXForm3d_GetIn(&Weapon->XForm, &In); geXForm3d_GetUp(&Weapon->XForm, &Up); geXForm3d_GetLeft(&Weapon->XForm, &Rt);
Front = Weapon->XForm.Translation;
geVec3d_AddScaled(&Front, &In, 10000.0f, &Back);
World = GenVSI_GetWorld(VSI); assert(World);
// Find out what direction the rocket needs to go to hit
if (geWorld_Collision(World, NULL, NULL, &Front, &Back, Impact = Collision.Impact; else Impact = Back;
// Position the Weapon_Blaster under the lower left arm geVec3d_AddScaled(&Front, &In, 70.0f, &Front); geVec3d_AddScaled(&Front, &Up, -10.0f, &Front); geVec3d_AddScaled(&Front, &Rt, -10.0f, &Front);
XFormFromVector(&Front, &Impact, 0.0f, &Weapon->XForm);
// HACK!!! Rocket is backwards, so rotate about up vector 180 // Rotate the thing 180
// Play the "take off" sound GenVSI_PlaySound(VSI, SOUND_INDEX_BLASTER, &Player->XForm.Translation);
Player->NextWeaponTime = GenVSI_GetTime(VSI) + 0.0f;
Player->VPos = Player->XForm.Translation;
// This next part is the Decal Manager. If you don’t have it, take it out.
if (geWorld_Collision(World, NULL, NULL, &Front, &Back, { GE_RGBA RGBA_Array = {255, 255, 255, 200};
DecalMgr_AddDecal(Globals.dMgr, DECAL_SCORCHMED1, -1.0f, } // This ends the Decal Manager. }
Remember, if you don’t use the DecalManager, take it out. Next got the FireWeapon function. Add:
case 5: FireFlame(VSI, Player, Time); break;
Make sure the case is the next weapon. It’s not good to skip any numbers. Next, in GMain.c, about line 123, add:
GenVSI_SetClassSpawn(VSI, "ItemShredder", Item_ShredderSpawn, NULL); GenVSI_SetClassSpawn(VSI, "ItemShredderAmmo", Item_ShredderAmmoSpawn, NULL); GenVSI_SetClassSpawn(VSI, "ItemFlame", Item_FlameSpawn, NULL); GenVSI_SetClassSpawn(VSI, "ItemFlameAmmo", Item_FlameAmmoSpawn, NULL);
GenVSI_SetClassSpawn(VSI, "AttackerTurret", Attacker_TurretSpawn, Attacker_TurretDestroy);
Then, about 146, add: GenVSI_ProcIndex(VSI, 9, Item_ControlHealth); GenVSI_ProcIndex(VSI, 11, Flame_Control);
Then, about 167: GenVSI_ProcIndex(VSI, 8, Shredder_Control); GenVSI_ProcIndex(VSI, 9, Item_ControlHealth); GenVSI_ProcIndex(VSI, 10, Flame_Control);
Then, 340: GenVSI_SetClientInventory(VSI, Player->ClientHandle, ITEM_SHREDDER, 0, GE_FALSE); GenVSI_SetClientInventory(VSI, Player->ClientHandle, ITEM_FLAME, 0, GE_FALSE);
Now, in GMain.h, about line 39: #define ACTOR_INDEX_ARMOR 9 #define ACTOR_INDEX_FLAME 10 #define ACTOR_INDEX_FLAME_AMMO 11
About line 87: #define ITEM_ROCKETS 2 #define ITEM_SHREDDER 3 #define ITEM_FLAME 4
About 133: // Flame #define FLAME_RESPAWN 10.0f #define FLAME_AMMO_RESPAWN 30.0f
#define FLAME_AMOUNT 25 #define FLAME_MAX_AMOUNT 200 #define FLAME_AMMO_AMOUNT 50
Line 202: geBoolean Shredder_Control(GenVSI *VSI, void *PlayerData, float Time); geBoolean Flame_Control(GenVSI *VSI, void *PlayerData, float Time);
Line 218: geBoolean
Item_ShredderSpawn(GenVSI *VSI, void *PlayerData, void *ClassData, geBoolean
Item_ShredderAmmoSpawn(GenVSI *VSI, void *PlayerData, geBoolean
Item_FlameSpawn(GenVSI *VSI, void *PlayerData, geBoolean
Item_FlameAmmoSpawn(GenVSI *VSI, void *PlayerData,
In Genvs.h, add somewhere in the file: // ItemFlame #pragma GE_Type("Item.ico") typedef struct ItemFlame { #pragma GE_Published geVec3d Origin; #pragma GE_Origin(Origin) } ItemFlame;
// ItemFlameAmmo #pragma GE_Type("Item.ico") typedef struct ItemFlameAmmo { #pragma GE_Published geVec3d Origin; #pragma GE_Origin(Origin) } ItemFlameAmmo;
Now, in Items.c, add this big block at about line 241: //================================================= // Item_ControlFlame //================================================= static geBoolean Item_ControlFlame(GenVSI *VSI, void *PlayerData, float Time) { geVec3d Pos; GPlayer *Player;
Player = (GPlayer*)PlayerData;
if (GenVSI_GetTime(VSI) < Player->NextThinkTime) return GE_TRUE;
if (Player->ViewIndex == 0xffff) {
GenVSI_SpawnFx(VSI, FX_EXPLODE2, &Player->XForm.Translation, Player->ViewIndex = ACTOR_INDEX_SHREDDER; }
Pos = Player->XForm.Translation; geXForm3d_RotateY(&Player->XForm, Time*2.0f); Player->XForm.Translation = Pos; return GE_TRUE; }
//================================================ // Item_ControlFlameAmmo //================================================ static geBoolean Item_ControlFlameAmmo(GenVSI *VSI, void *PlayerData, float Time) { GPlayer *Player; Player = (GPlayer*)PlayerData;
if (GenVSI_GetTime(VSI) < Player->NextThinkTime) return GE_TRUE;
if (Player->ViewIndex == 0xffff) // Time to respawn {
GenVSI_SpawnFx(VSI, FX_EXPLODE2, &Player->XForm.Translation, Player->ViewIndex = ACTOR_INDEX_SHREDDER_AMMO; }
return GE_TRUE; }
//=================================================== // Item_TriggerFlame //=================================================== static
geBoolean Item_TriggerFlame(GenVSI *VSI, void *PlayerData, { GPlayer *Player, *Target; Player = (GPlayer*)PlayerData; Target = (GPlayer*)TargetData;
if (GenVSI_GetTime(VSI) < Player->NextThinkTime) return GE_TRUE;
if (Target->ClientHandle == CLIENT_NULL_HANDLE) return GE_TRUE;
if (Target->InventoryHas[ITEM_FLAME]) return GE_TRUE;
// Make the ammo dissapear Player->ViewIndex = 0xffff; Player->NextThinkTime = GenVSI_GetTime(VSI) + FLAME_RESPAWN; // Make them come back at a later time
GenVSI_PlaySound(VSI, SOUND_INDEX_PICKUP_WEAPON2,
Target->InventoryHas[ITEM_FLAME] = GE_TRUE; Target->CurrentWeapon = ITEM_FLAME;
if (Target->ClientHandle != CLIENT_NULL_HANDLE) GenVSI_SetClientWeapon(VSI, Target->ClientHandle, ITEM_FLAME);
Target->Inventory[ITEM_FLAME] += FLAME_AMOUNT;
// Actors don't have a client handle if (Target->ClientHandle != CLIENT_NULL_HANDLE) { UpdateClientInventory(VSI, Target, ITEM_FLAME);
GenVSI_ConsoleHeaderPrintf(VSI, Target->ClientHandle, }
return GE_TRUE; }
//===================================================== // Item_TriggerFlameAmmo //===================================================== static geBoolean Item_TriggerFlameAmmo(GenVSI *VSI, void *PlayerData, void *TargetData, void* data) { GPlayer *Player, *Target;
Player = (GPlayer*)PlayerData; Target = (GPlayer*)TargetData;
if (GenVSI_GetTime(VSI) < Player->NextThinkTime) return GE_TRUE;
if (Target->ClientHandle == CLIENT_NULL_HANDLE) return GE_TRUE;
if (Target->Inventory[ITEM_FLAME] >= FLAME_MAX_AMOUNT) return GE_TRUE;
// Make the ammo disappear Player->ViewIndex = 0xffff; Player->NextThinkTime = GenVSI_GetTime(VSI) + FLAME_AMMO_RESPAWN; // Make them come back at a later time
// Increase the items of the player the touches this ammo Target->Inventory[ITEM_FLAME] += FLAME_AMMO_AMOUNT;
if (Target->Inventory[ITEM_FLAME] > FLAME_MAX_AMOUNT) Target->Inventory[ITEM_FLAME] = FLAME_MAX_AMOUNT;
GenVSI_PlaySound(VSI, SOUND_INDEX_PICKUP_WEAPON1,
// Actors don't have a client handle if (Target->ClientHandle != CLIENT_NULL_HANDLE) { UpdateClientInventory(VSI, Target, ITEM_FLAME);
GenVSI_ConsoleHeaderPrintf(VSI, Target->ClientHandle, }
return GE_TRUE; }
I think that’s about it. Just make an actor, define all the actor indexes, and change all the code above to point to your flame thrower actor and ammo. With the way the code is, you will die very quickly. It shoots so fast, it’s over before you even knew it begun. If you want a longer flame, just change:
if (Player->Time >= 0.40f) GenVSI_DestroyPlayer(VSI, PlayerData);
That number is the time when it will stop. The bigger the number, the longer the stream. You’ll also probably want to change the FX system to your own, but the included FX works fine. Plenty of fire and plenty of smoke. E-mail me at bonolo1@core.com
Get Genesis3D University on CD ! The Genesis3d
UNIVERSITY [G3DU] CD ******
|
|||
To report "errors" and to post comments e-mail us at KenDeel@mail.com This Website Created
and Hosted by OtherWorlds InterActive. |