Posté le: 21/03/10 12:26 Sujet du message: Library: System Creator
Sépare la carte en 16 carrés identiques.
Va permettre, de façon aléatoire, d'en attribuer 14 qui seront des systèmes solaires (étoile+planètes+mines+asteroides) et 2 spéciaux (un champ de nébula, un champ de vaisseaux morts)
Sur les 14 systèmes solaires, 12 serviront comme point de départ des 12 joueurs, 2 seront libres. (Si 6 joueurs, bah y'en aura 8 de libres)
globals
integer array SsSunId [3] //Id des unités qui forment les étoiles
integer array SsPlaneteId [8] //Id des différentes planètes
integer array SsNebulaId [5] //Id des nebulas (dummys avec des couleurs flashys)
integer array SsDeadShipId [4] //Id des destructables en forme de vaisseaux détruits
unit DummyAttackerNebula //le dummy qui sert à checker la présence de vaisseaux dans le champ de nebula
unit DummyAttackerPirate //le dummy qui sert à checker la présence de vaisseaux dans le champ de destructables vaisseaux
rect array Quadrant [16] //La carte est divisée en 16 carrés similaires
real array QuadrantX [16] //Centre d'une région
real array QuadrantY [16]
boolean array StartLocationPicked [16] //booléen pour vérifier qu'un secteur est attribué à un joueur
unit array PlanetWithBonusPulsar [50] //pour retrouver pour le système d'income les planètes avec bonus de pulsar (gold)
unit array PlanetWithBonusIron [50] //idem pour l'iron (bois)
integer PlanetWithBonusPulsarMax = 0 //pour avoir le nombre max des planètes en question
integer PlanetWithBonusIronMax = 0
//Planets with bonus
constant integer PLANETINCOMEBONUS_PULSAR ='A00G' //skill qu'une planète avec bonus possède
constant integer PLANETINCOMEBONUS_IRON ='A00H'
//Asteroids data
private constant integer ASTEROID_ID = 'B000' //ID d'un destructable asteroide
private constant integer ASTEROID_AMOUNT_FIELD = 40 //nombre d'asteroides dans le champ d'asteroides
private constant integer ASTEROID_AMOUNT_QUADRANT = 40 //nombre d'asteroides qui séparent certains quadrants
private constant real ASTEROID_RADIUS = 3000. //zone de spawn pour les asteroides
//dead ship data
private constant integer DEADSHIP_AMOUNT_FIELD = 40 //idem pour les destructables vaisseaux
private constant real DEADSHIP_RADIUS = 1000.
//nebula data
private constant integer NEBULA_AMOUNT_FIELD = 80 //idem pour les nebula
private constant real NEBULA_RADIUS = 1000.
//Mine data
private constant integer MINE_SMALL = 'n000' //équivelent de mine d'or
private constant integer MINE_BIG = 'n001'
private constant real MINE_RADIUS = 1500.//zone de spawn des mines
private constant integer MINE_AMOUNT = 4 //nombre de mine/secteur
//misc
private constant integer MAXQUADRANT = 15 //(real number-1) il y a 16 quadrants, mais on part de 0 dans les boucles
private constant real TIMEOUT_SYSTEM = 0.30 //interval de création des quadrants
private constant real TIMEOUT_ASTEROID = 0.01 //interval de création des asteroides
private constant real ORBIT = 500. //radius between stars and orbit circle
private constant integer SOLARSYSTEM_AMOUNT = 14 //nombre de systèmes solaires complets (14 sur les 16 quadrants, le 15 et le 16 sont le champ de nebula et le champ de vaisseaux morts
endglobals
private struct strasteroids
integer i
real x
real y
integer amount
endstruct
//fonction périodique qui créée les asteroides. J'utilise un timer pour diminuer le freeze qui a lieu si je créé tout d'un coup
private function SpawnAsteroids takes nothing returns nothing
local timer t = GetExpiredTimer()
local strasteroids dat = GetTimerData(t)
local real x = dat.x+GetRandomReal(-ASTEROID_RADIUS,ASTEROID_RADIUS)
local real y = dat.y+GetRandomReal(-ASTEROID_RADIUS,ASTEROID_RADIUS)
//initialization de la fonction ci-dessus
private function CreateAsteroids takes real x, real y,integer whichAmount returns nothing
local timer t = NewTimer()
local strasteroids dat = strasteroids.create()
set dat.i = 0
set dat.amount = whichAmount
set dat.x = x
set dat.y = y
call SetTimerData(t, dat)
call TimerStart (t, TIMEOUT_ASTEROID, true, function SpawnAsteroids )
endfunction
//Pour créer les champs d'asteroides sur certains quadrants
private function CreateFieldAsteroids takes integer whichQuadrant returns nothing
local real x = GetRectMaxX(Quadrant[whichQuadrant])
local real y = GetRectMaxY(Quadrant[whichQuadrant])
//Création du champ de vaisseaux morts
private function CreateFieldPirate takes nothing returns nothing
local integer i = 0
local real x = 0.
local real y = 0.
call DisplayAllNoSound("Game","please wait... creating dead ships field for Quadrant 14")
//Ce dummy attaque toute unité à portée.
//Quand une attaque est détectée, un autre système va créer des unités NEUTRAL_AGRRESIVE
set DummyAttackerPirate = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE),'o010',QuadrantX[14],QuadrantY[14],0.)
//Création des vaisseaux morts
loop
set i = i + 1
exitwhen i > DEADSHIP_AMOUNT_FIELD
set x = QuadrantX[14]+GetRandomReal(-DEADSHIP_RADIUS,DEADSHIP_RADIUS)
set y = QuadrantY[14]+GetRandomReal(-DEADSHIP_RADIUS,DEADSHIP_RADIUS)
call CreateDestructable(SsDeadShipId[GetRandomInt(0,3)], x,y,GetRandomReal(0.,360.),GetRandomReal(0.25,0.5),1)
endloop
endfunction
//Idem pour la Nebula
private function CreateFieldNebula takes nothing returns nothing
local integer i = 0
local real x = 0.
local real y = 0.
local unit nebula
call DisplayAllNoSound("Game","please wait... creating nebula field for Quadrant 15")
//Ce dummy attaque toute unité à portée.
//Quand une attaque est détectée, un autre système va créer un éclair et endommager le vaisseau attaqué
set DummyAttackerNebula = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE),'o00Z',QuadrantX[15],QuadrantY[15],0.)
set i = 0
//Spawn des nebulas
loop
set i = i + 1
exitwhen i > NEBULA_AMOUNT_FIELD
set x = QuadrantX[15]+GetRandomReal(-NEBULA_RADIUS,NEBULA_RADIUS)
set y = QuadrantY[15]+GetRandomReal(-NEBULA_RADIUS,NEBULA_RADIUS)
set nebula = CreateUnit(Player(11),SsNebulaId[GetRandomInt(0,4)],x,y,GetRandomReal(0.,360.))
call SetUnitColor(nebula,GetPlayerColor(Player(GetRandomInt(0,12))))
call SetUnitFlyHeight(nebula, GetRandomReal(0.,300.),0.)
endloop
set nebula = null
endfunction
//Spawn des mines à partir du centre d'un quadrant
private function CreateMine takes real x1, real y1 returns nothing
local integer i = 0
local real x2 = 0.
local real y2 = 0.
//grosse mine: 1 par quadrant "habitable" (tous sauf champ vaisseau mort et nebula)
set x2 = x1+GetRandomReal(-MINE_RADIUS,MINE_RADIUS)
set y2 = y1+GetRandomReal(-MINE_RADIUS,MINE_RADIUS)
call AddResourceAmount(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),MINE_BIG,x2,y2,GetRandomReal(0.,360.)),32500)
//petite mine: 4 par quadrant "habitable" (tous sauf champ vaisseau mort et nebula)
loop
set i = i + 1
exitwhen i > MINE_AMOUNT
set x2 = x1+GetRandomReal(-MINE_RADIUS,MINE_RADIUS)
set y2 = y1+GetRandomReal(-MINE_RADIUS,MINE_RADIUS)
call AddResourceAmount(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),MINE_SMALL,x2,y2,GetRandomReal(0.,360.)),12500)
endloop
//On ordonne de créer les asteroides des quadrants une fois les mines créées
call CreateAsteroids(x1,y1,ASTEROID_AMOUNT_QUADRANT)
endfunction
//Pour créer les planètes à partir du centre d'un quadrant
private function CreatePlanete takes real x1, real y1 returns nothing
local integer i = 0
local integer j = 0
local real x2 = 0.
local real y2 = 0.
local real angle = 0
local unit planet = null
//à partir du centre du quadrant
//3 orbites différentes
//3 planètes par orbites
loop
set i = i + 1
exitwhen i > 3
set j = 0
loop
set j = j + 1
exitwhen j > 3
set angle = angle+60.
set x2 = x1+j*ORBIT*Cos(angle)
set y2 = y1+j*ORBIT*Sin(angle)
// création d'une planète
set planet = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),SsPlaneteId[GetRandomInt(0,7)],x2,y2,0.)
//Là on vérifie si la planète est à bonus d'or /bois et on la stocke pour le système d'income
if GetUnitAbilityLevel(planet,PLANETINCOMEBONUS_PULSAR)>= 1 then
set PlanetWithBonusPulsar[PlanetWithBonusPulsarMax]=planet
set PlanetWithBonusPulsarMax = PlanetWithBonusPulsarMax +1
elseif GetUnitAbilityLevel(planet,PLANETINCOMEBONUS_IRON)>= 1 then
set PlanetWithBonusIron[PlanetWithBonusIronMax]=planet
set PlanetWithBonusIronMax = PlanetWithBonusIronMax +1
endif
//On dégage le rallye point de la planète qui ne sert à rien
call UnitRemoveAbility(planet,'ARal')
endloop
endloop
//Une fois les planètes créées, on lance la création des mines du quadrant
call CreateMine(x1,y1)
set planet = null
endfunction
//Pour créer les soleils à partir du centre d'un quadrant
private function SystemCreator takes integer whichQuadrant returns nothing
local unit sun = null
call DisplayAllNoSound("Game","please wait... creating solar system for Quadrant "+ I2S(whichQuadrant))
set sun = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),SsSunId[0],QuadrantX[whichQuadrant],QuadrantY[whichQuadrant],270.)
call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),SsSunId[1],QuadrantX[whichQuadrant],QuadrantY[whichQuadrant],270.)
call CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),SsSunId[2],QuadrantX[whichQuadrant],QuadrantY[whichQuadrant],270.)
//Une fois les dummys qui forment le soleil créées, on lance les planètes
call CreatePlanete(QuadrantX[whichQuadrant],QuadrantY[whichQuadrant])
set sun = null
endfunction
private struct str
integer i
integer asteroidfield
integer system
endstruct
//Fonction périodique pour éviter de tout créer en même temps, et donc éviter un gros freeze
private function IniCreator takes nothing returns nothing
local timer t = GetExpiredTimer()
local str dat = GetTimerData(t)
//14 systèmes "habitables" + 16 quadrants (les 14 étant compris dans les 16)
if dat.i < SOLARSYSTEM_AMOUNT+MAXQUADRANT then
//Create 12 systems (one per player)+2 empty systems
if dat.system < SOLARSYSTEM_AMOUNT then
call SystemCreator(dat.system)//Création systèmes habitables, 14 en tout
set dat.system = dat.system + 1
elseif dat.i == SOLARSYSTEM_AMOUNT then
call CreateFieldPirate()//création champ de vaisseaux morts
elseif dat.i == MAXQUADRANT+1 then
call CreateFieldNebula()//création champ nebula
elseif dat.i >= MAXQUADRANT+2 and dat.asteroidfield <= MAXQUADRANT then
//Pour tous les quadrants, on créé un champ d'asteroide de sorte que chaque quadrant qui est tangeant par son angle
//à un autre soit séparé par un champ d'asteroide
if dat.asteroidfield!=3 and dat.asteroidfield!=7 and dat.asteroidfield!=11 and dat.asteroidfield!=MAXQUADRANT then
call CreateFieldAsteroids(dat.asteroidfield)
endif
set dat.asteroidfield = dat.asteroidfield + 1
endif
set dat.i = dat.i + 1
else
//Une fois la création complète de la carte terminée, on release le timer
call ReleaseTimer(t)
call dat.destroy()
//Et on peut lancer la partie (autre library)
call RunGame()
endif
endfunction
//Fonction qui permet d'attribuer aléatoirement quel quadrant sera habitable ou non (14 habitables et 2 pour les champs nebula/pirate)
private function SetRandomQuadrant takes nothing returns integer
local integer i = 0
local integer random = 0
loop
exitwhen i > MAXQUADRANT//On s'arrête une fois l'ensemble des secteurs checkés
set random = GetRandomInt(0,MAXQUADRANT) //random
if StartLocationPicked[random]==false then//on regarde si le secteur est déjà pris
set StartLocationPicked[random]=true//on pourra savoir que ce secteur est déjà pris
return random//on renvoie la valeur (l'ID) du quadrant qui va être utilisé
endif
set i = i + 1
endloop
return 16
endfunction
//Première fonction appelée pour la création de la carte
private function StartMapCreation takes nothing returns boolean
local timer t = NewTimer() //Parce que tout va se faire par timer pour éviter les longs freeze
local str dat = str.create()
local integer i = 0
local integer randomquadrant = 0
call SetSkyModel( "Environment\\Sky\\BlizzardSky\\BlizzardSky.mdx" )//Add the sky model
//On enlève tout contrôle aux joueurs et on affiche un écran noir pendant le chargement de la création
call CinematicModeBJ(true, bj_FORCE_ALL_PLAYERS ) //disabled in Start trigger
call CinematicFadeBJ(bj_CINEFADETYPE_FADEOUT,0.,"ReplaceableTextures\\CameraMasks\\White_mask.blp",0,0,0,0)
set randomquadrant = SetRandomQuadrant()//On attribue les emplacements des quadrants et ce à quoi ils serviront
set QuadrantX[i]=GetRectCenterX(Quadrant[randomquadrant])
set QuadrantY[i]=GetRectCenterY(Quadrant[randomquadrant])
set i = i + 1
endloop
//C'est partit pour la création de l'ensemble des objets de chaque quadrant
set dat.i = 0
set dat.asteroidfield = 0
set dat.system = 0
call SetTimerData(t, dat)
call TimerStart (t, TIMEOUT_SYSTEM, true, function IniCreator )
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 15
set StartLocationPicked[i]=false//précaution: par défaut aucun quadrant n'est utilisé
set i = i + 1
endloop
set SsSunId[0] = 'o00G'//variables
set SsSunId[1] = 'o002'
set SsSunId[2] = 'o001'
set SsPlaneteId[0] = 'o004'
set SsPlaneteId[1] = 'o009'
set SsPlaneteId[2] = 'o006'
set SsPlaneteId[3] = 'o003'
set SsPlaneteId[4] = 'o005'
set SsPlaneteId[5] = 'o007'
set SsPlaneteId[6] = 'o008'
set SsPlaneteId[7] = 'o011'
set SsNebulaId[0] = 'o00U'
set SsNebulaId[1] = 'o00W'
set SsNebulaId[2] = 'o00X'
set SsNebulaId[3] = 'o00V'
set SsNebulaId[4] = 'o00Y'
set SsDeadShipId[0] = 'B002'
set SsDeadShipId[1] = 'B003'
set SsDeadShipId[2] = 'B004'
set SsDeadShipId[3] = 'B000'
set Quadrant[0]=Rect(-10000,-10000,-5000,-5000)//La carte est un carré de 16 carrés égaux
set Quadrant[1]=Rect(-5000,-10000,0,-5000)
set Quadrant[2]=Rect(0,-10000,5000,-5000)
set Quadrant[3]=Rect(5000,-10000,10000,-5000)
set Quadrant[4]=Rect(-10000,-5000,-5000,0)
set Quadrant[5]=Rect(-5000,-5000,0,0)
set Quadrant[6]=Rect(0,-5000,5000,0)
set Quadrant[7]=Rect(5000,-5000,10000,0)
set Quadrant[8]=Rect(-10000,0,-5000,5000)
set Quadrant[9]=Rect(-5000,0,0,5000)
set Quadrant[10]=Rect(0,0,5000,5000)
set Quadrant[11]=Rect(5000,0,10000,5000)
set Quadrant[12]=Rect(-10000,5000,-5000,10000)
set Quadrant[13]=Rect(-5000,5000,0,10000)
set Quadrant[14]=Rect(0,5000,5000,10000)
set Quadrant[15]=Rect(5000,5000,10000,10000)
call TriggerRegisterTimerEventSingle( t, 0.05 )//Dès le début de la partie on lance les opérations
call TriggerAddCondition( t, Condition( function StartMapCreation ) )
endfunction
endlibrary
_________________
Dernière édition par jk2pach le 06/04/10 22:44; édité 2 fois
Page 1 sur 1 La question posée dans ce topic a été résolue !
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum