Commit 45a761dd authored by Toussaint Etienne's avatar Toussaint Etienne

merge

parents 132d0f6b aa39d7e3
......@@ -7,6 +7,7 @@ import smtplib, argparse
from email.mime.text import MIMEText
parser = argparse.ArgumentParser()
parser.add_argument("mail", help="mail of the receiver")
parser.add_argument("filename", help="file containing the corp of the mail")
args = parser.parse_args()
......@@ -14,10 +15,11 @@ with open(args.filename) as fp:
# Create a text/plain message
msg = MIMEText(fp.read())
msg['Subject'] = 'Continuous Integration of the the_dungeon_project : Error'
msg['From'] = 'the_dungeon_project@ci.org'
msg['To'] = args.mail
msg['Reply-To'] = 'ens-info-genielog-2015@lists.crans.org'
msg['To'] = 'ens-info-genielog-2015@lists.crans.org'
msg['Subject'] = 'Continuous Integration of the the_dungeon_project : Error'
# Send the message via our own SMTP server.
s = smtplib.SMTP('smtp.crans.org')
......
......@@ -6,12 +6,20 @@ make clean
if ! make; then
echo 'Compilation error in the master branch.' > CI/msg
echo 'Result of make :\n' >> CI/msg
make 2>> CI/msg
make 2>> CI/msgerror
cat CI/msgerror >> CI/msg
echo '\n-- \nCI script' >> CI/msg
# Kludge : pas de serveur smtp accessible depuis la salle.
scp CI/msg fardale@acerarien.crans.org:the_dungeon_project/
ssh fardale@acerarien.crans.org './the_dungeon_project/mailci.py ./the_dungeon_project/msg'
scp CI/msg fardale@crash-test.crans.org:the_dungeon_project/
ssh fardale@crash-test.crans.org './the_dungeon_project/mailci.py "ens-info-genielog-2015@lists.crans.org" ./the_dungeon_project/msg'
rm -f CI/msg
echo 'It seems that your commit breaks the compilation of the project.' > CI/msg
echo 'Result of make :\n' >> CI/msg
cat CI/msgerror >> CI/msg
echo '\n-- \nCI script' >> CI/msg
# Kludge : pas de serveur smtp accessible depuis la salle.
scp CI/msg fardale@crash-test.crans.org:the_dungeon_project/
ssh fardale@crash-test.crans.org "./the_dungeon_project/mailci.py $(git log -n 1 | grep Author | sed "s/.*<\(.*\)>/\1/g") ./the_dungeon_project/msg"
fi
exit 0
......@@ -61,7 +61,7 @@ $(BIN)%.class : $(SRC)%.java
# Hack pour bin/
hack :
@mkdir -p bin;
@mkdir -p bin/log;
buildplay: all
cd bin/; java -cp $(LIB)*:. graphics.guiSkeleton.Igniter_Main
......
......@@ -13,13 +13,31 @@ To run
################### HOW TO PLAY ###################
1)Launch the game. 2)On the main panel, you may : 2.1) single player : starts the game in a single player mode 2.2) multi player : TODO 2.3) configuration : you may configure the keys used to play the game 2.4) IGP : stands for "in game programming" : you may configure your own A.I. for the game 2.5) exit : leaves the game
1)Launch the game.
3)Once you are in game : For now, the basic configuration is : Move left : left_arrow Move right : right_arrow Move up : up_arrow Move down : down_arrow Attack : a Spell : s Back to main : escape
2)On the main panel, you may :
2.1) single player : starts the game in a single player mode
2.2) multi player : enables to create/join a multi player mode
2.3) configuration : you may configure the keys used to play the game
2.4) IGP : stands for "in game programming" : you may configure your own A.I. for your game allies
2.5) exit : leaves the game : be careful configuration keys are not registered
3)Default commands:
-Move left : left_arrow
-Move right : right_arrow
-Move up : up_arrow
-Move down : down_arrow
-Attack : a
-Ability1 : z
-Ability1 : e
-Ability1 : r
-Back to main : escape
################### HOW TO DOCUMENT ###################
To document the project, you need the package doxygen. It will create a HTML documentation from the code. To have inheritance graphs, please install graphivz.
To document the project, you need the package doxygen.
It will create a HTML documentation from the code.
To have inheritance graphs, please install graphivz.
English versions :
......@@ -37,26 +55,6 @@ Without graphivz
make doc-html2-fr
################### HOW TO PLAY ###################
1)Launch the game.
2)On the main panel, you may :
2.1) single player : starts the game in a single player mode
2.2) multi player : TODO
2.3) configuration : you may configure the keys used to play the game
2.4) IGP : stands for "in game programming" : you may configure your own A.I. for the game
2.5) exit : leaves the game
3)Once you are in game :
For now, the basic configuration is :
Move left : left_arrow
Move right : right_arrow
Move up : up_arrow
Move down : down_arrow
Attack : a
Spell : s
Back to main : escape
################### PRINCIPLE OF THE GAME ###################
TODO
......@@ -87,6 +85,4 @@ The following people were the developers :
-Ringeade Clément
-Toussaint Etienne
-Thomas Colin
-Ursu Bogdan
TODO : missing names to fill because not registered
-Ursu Bogdan
\ No newline at end of file
......@@ -40,7 +40,7 @@ public class AIControler {
ai = new DefenderEntity(gameContent,dmr);
break;
default:
LOGGER.warning("Trying to instanciate unrecognized type of AI.");
LOGGER.severe("Trying to instanciate unrecognized type of AI.");
break;
}
list.add(ai);
......
......@@ -24,7 +24,7 @@ public class AbilityRoster {
abilityGenerator =
() -> new Ability(
1,
500,
AbilityIconKeys.NULL_ABILITY,
Action.ATTACK,
new ArrayList<EffectDescriptor>()
......
package core.event;
import core.gamestate.GameContent;
/**
* Event received by Client when an entity die.
* @author Begel Myriam
* Just remove it from the GameState.
*/
public class ToClientDeathEvent implements ClientEvent {
private int entityID;
public ToClientDeathEvent(int entityID){
this.entityID = entityID;
}
public int getEntityID(){
return entityID;
}
private static final long serialVersionUID = 1L;
@Override
public boolean execute(GameContent gameContent) {
return gameContent.getGameState().removeEntity(entityID);
}
@Override
public Event resolve(GameContent gameContent) {
return null;
}
}
package core.event;
import artificial_intelligence.AIControler;
import core.gamestate.Entity;
import core.gamestate.GameContent;
/**
* This event is executed when an entity dies.
* @author Guerquin Arnaud
*
* This event is executed by Server when an entity dies.
* @author Begel Myriam
* We kill the AI if it is one (if not, the method just do nothing).
* In resolve, we send to the client almost the same Event: AI is not on ClientSide
* so we don't kill AI.
*/
public class ToServerDeathEvent implements ClientEvent {
public class ToServerDeathEvent implements ServerEvent {
private int entityID;
public ToServerDeathEvent(int entityID){
......@@ -19,17 +20,13 @@ public class ToServerDeathEvent implements ClientEvent {
private static final long serialVersionUID = 1L;
@Override
public boolean execute(GameContent gameContent) {
LOGGER.info(entityID+" is dead");
//if (AIControler.killOne(entityID);
Entity entity = gameContent.getGameState().getEntity(entityID);
//gameContent.getGameState().removeEntity(entity);
return false;
AIControler.killOne(entityID);
return gameContent.getGameState().removeEntity(entityID);
}
@Override
public Event resolve(GameContent gameContent) {
// TODO Auto-generated method stub
return null;
return new ToClientDeathEvent(entityID);
}
}
......@@ -2,10 +2,18 @@ package core.gamestate;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;
import core.event.Event;
import core.event.ToServerDeathEvent;
import core.zone.Zone;
import gameloop.DummyLocalGameLoop;
import gameloop.ServerLoop;
import graphics.guiSkeleton.entityDisplayer.EntityDisplayerType;
import logging.Logging;
import map_generation.tiles.TilePropertyVector;
import network.NetworkConnection;
import network.NetworkObject;
/**
* This class represents an Entity able to be hit and die.
......@@ -39,15 +47,25 @@ public class Being extends Entity {
private DamageTypeVector dtv;
/**
* Being's constructor
* @param name the Being's name.
* @param speciesName the name of the species of the Being.
* @param posX the Being's center X position. Must be in Point Coordinate.
* @param posY the Being's center Y position. Must be in Point Coordinate.
* @param ID the Being's ID.
* @param owner the Being's Relayer ID.
* @param species the Being's species.
*/
* @param collisionBox
* @param tpv
* @param visibility
* @param type
* @param triggers
* @param HP
* @param def
* @param mental
* @param dtv
* @param hitbox
*/
public Being(String name,String speciesName,int posX,int posY,int ID,int owner,Zone collisionBox,TilePropertyVector tpv,Zone visibility,EntityDisplayerType type,List<TriggerDescriptor> triggers,
int HP,int def,int mental,DamageTypeVector dtv,Zone hitbox) {
super(name,speciesName,posX, posY, ID,owner, collisionBox, tpv, visibility, type,triggers);
......@@ -80,6 +98,18 @@ public class Being extends Entity {
public boolean takeDamage(int damage){
HP=Math.min(maxHP, Math.max(HP-damage, 0));
if (HP==0){
Event event = new ToServerDeathEvent(this.getID());
Logger LOGGER = new Logging().getLogger();
NetworkConnection<NetworkObject> network = DummyLocalGameLoop.getInstance().getNetworkConnection();
if (network==null){
LOGGER.severe("NetworkConnection null, Being"+this.getID()+" can't die");
} else {
LOGGER.info("Death of "+this.getID()+" is send");
network.sendEvent(event);
}
}
return isDead();
}
......@@ -116,24 +146,24 @@ public class Being extends Entity {
*/
public int getMental() {
return mental;
}
/**
* Returns the Being's current Exp
* @return the Being's current Exp
*/
//TODO : implement exp
public int getExp() {
return 50;
}
/**
* Returns the Being's maxExp
* @return Returns the Being's maxExp
*/
//TODO : implement maxExp
public int getMaxExp() {
return 100;
}
/**
* Returns the Being's current Exp
* @return the Being's current Exp
*/
//TODO : implement exp
public int getExp() {
return 50;
}
/**
* Returns the Being's maxExp
* @return Returns the Being's maxExp
*/
//TODO : implement maxExp
public int getMaxExp() {
return 100;
}
public Zone getHitbox() {
......
......@@ -8,6 +8,7 @@ import core.zone.Point;
import core.zone.Zone;
import graphics.guiSkeleton.entityDisplayer.EntityDisplayerType;
import map_generation.tiles.TilePropertyVector;
import map_generation.tiles.TileType;
public class EntitySpecies{
......@@ -59,8 +60,11 @@ public class EntitySpecies{
}
//TODO change this
public boolean canSpawn(Point p) {
return true;
public boolean canSpawn(TileType tile) {
switch (tile){
case WATER : return false;
default : return true;
}
}
}
package core.gamestate;
import core.zone.Point;
import map_generation.map.Map;
import network.NetworkConnection;
import network.NetworkObject;
......@@ -9,14 +10,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import core.zone.Point;
/**
* Just a class to contain a Map and a GameState
*
* Possible improvement: design a readonly interface for it, to give to the gui to ensure she isn't able to modify it.
*
*
* @author Dupriez Thomas
* @author Guerquin Arnaud
*
......@@ -51,7 +50,7 @@ public class GameContent implements Serializable{
* Relayer dmr = Relayers.addNewRelayer(2,AItest,this);
* AIControler.add(gameContent,dmr);
*/
System.out.println("One gameContent created");
System.out.println("GameContent class: One gameContent created by"+Thread.currentThread().getId());
}
public Map getMap() {
......@@ -78,7 +77,7 @@ public class GameContent implements Serializable{
return gameState.getOnlyBeings();
}
public List<Being> getAllBeings() {
return gameState.getAllBeings();
return gameState.getAllBeings();
}
public List<Character> getOnlyCharacters() {
......@@ -95,6 +94,10 @@ public class GameContent implements Serializable{
return players.get(i);
}
public ArrayList<Character> getAllPlayers() {
return players;
}
public void applyTrigger(NetworkConnection<NetworkObject> networkConnection) {
for(Entity e:triggerEntities){
e.checkTrigger(this,networkConnection);
......@@ -104,7 +107,7 @@ public class GameContent implements Serializable{
public void addTriggerToCheck(Entity e) {
triggerEntities.add(e);
}
public void removeTriggerToCheck(Entity e) {
triggerEntities.remove(e);
......
......@@ -4,7 +4,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import core.zone.Zone;
/**
......@@ -13,7 +12,6 @@ import core.zone.Zone;
*
*/
public class GameState implements Serializable{
private static final long serialVersionUID = 1L;
/**
* The list of entities in the gamestate.
......@@ -80,10 +78,12 @@ public class GameState implements Serializable{
* @return true if it was successfully removed. false otherwise.
*/
public boolean removeEntity(int id){
if(beings.removeIf(x->x.getID()==id))
if(beings.removeIf(x->x.getID()==id)){
return true;
if(characters.removeIf(x->x.getID()==id))
}
if(characters.removeIf(x->x.getID()==id)) {
return true;
}
return false;
}
......@@ -92,7 +92,7 @@ public class GameState implements Serializable{
* @param entity the entity to remove.
* @return true if it was successfully removed. false otherwise.
*/
boolean removeEntity(Entity entity){
public boolean removeEntity(Entity entity){
if(beings.remove(entity))
return true;
if(characters.remove(entity))
......
......@@ -7,6 +7,7 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Objects;
import map_generation.tiles.TileType;
import assets.UsedForLoadingSprites;
import core.zone.Point;
......@@ -87,8 +88,8 @@ public class SpeciesArray {
"Line"+lineError + message);
}
public static boolean canSpawn(Point p,String speciesName){
public static boolean canSpawn(TileType tile,String speciesName){
EntitySpecies species=array.get(speciesName);
return species!=null && species.canSpawn(p);
return species!=null && species.canSpawn(tile);
}
}
......@@ -2,9 +2,12 @@ package gameloop;
import core.event.Event;
import core.event.MapInit;
import core.event.ToClientDeathEvent;
import core.event.ToServerDeathEvent;
import core.gamestate.GameContent;
import core.relayer.Relayer;
import core.relayer.Relayers;
import graphics.graphical_abstraction.GraphicsMasterAbstraction;
import network.EndEvent;
import network.NetworkConnection;
import network.NetworkObject;
......@@ -33,14 +36,15 @@ public class DummyLocalGameLoop extends Thread{
public Relayer getFollowedRelayer() {
try {
relayerSemaphore.acquire();
System.out.println("Acquired relayer");
System.out.println("Acquired relayer "+ followedRelayer+ " by "+currentThread().getId());
return followedRelayer;
} catch (InterruptedException e) {
System.out.println("Problem with acquiring relayer...");
}finally {
//finally is almost always executed, unless an Interrupted exception or a System.exit appeared
System.out.println("Relayer is "+followedRelayer);
relayerSemaphore.release();
System.out.println("Released relayer");
System.out.println("Released relayer by "+currentThread().getId());
}
return followedRelayer;
......@@ -98,6 +102,9 @@ public class DummyLocalGameLoop extends Thread{
public synchronized void pauseGame()
{
isPlaying=false;
//do not release here
//relayerSemaphore.release();
System.out.println("Released relayer");
}
public synchronized boolean getIsPlaying()
......@@ -126,15 +133,15 @@ public class DummyLocalGameLoop extends Thread{
@Override
public void run() {
System.out.println("DummyLocalGameLoop Thread started");
System.out.println("DummyLocalGameLoop Thread started+"+currentThread().getId());
while (true) {
//System.out.println("DummyLocalGameLoopThread, game is "+isPlaying);
if (getIsPlaying()) {
System.out.println("DummyLocalGameLoopThread, game is "+isPlaying);
System.out.println("DummyLocalGameLoopThread,"+currentThread().getId()+ "game is "+isPlaying);
Event eventToReceive = null;
System.out.println("The game is on!");
while (!((eventToReceive = (Event) getNetworkConnection().receiveEvent(true)) instanceof EndEvent)) {
//System.out.println("DummyLocalGameLoop Thread: We have received an event!applying...");
//System.out.println("DummyLocalGameLoop Thread: We have received an event!applying...+"+eventToReceive);
eventToReceive.apply(gameContent);
if (eventToReceive instanceof MapInit) {
GameContent gc = DummyLocalGameLoop.getInstance().getContent();
......@@ -142,6 +149,10 @@ public class DummyLocalGameLoop extends Thread{
setFollowedRelayer(firstEntityRelayer);
relayerSemaphore.release();
}
if (eventToReceive instanceof ToClientDeathEvent && ((ToClientDeathEvent) eventToReceive).getEntityID()==followedRelayer.getCharacter().getID()) {
GraphicsMasterAbstraction.getInstance().changeGUIStateTo(GraphicsMasterAbstraction.GUIStates.GAME_OVER);
}
}
if (eventToReceive instanceof EndEvent)
System.out.println("DummyLocalGameLoop Thread: End Event Received!");
......
......@@ -23,10 +23,9 @@ public class GameStarter {
static public void startGameSinglePlayer()
{
NetworkConnection<NetworkObject>[] localConnections= LocalConnection.initiate();
NetworkConnection<NetworkObject>[] localConnections= LocalConnection.createNew();
NetworkConnection<NetworkObject> serverConnection = localConnections[0];
NetworkConnection<NetworkObject> clientConnection = localConnections[1];
ServerLoop dummyServerLoop=new ServerLoop(serverConnection);
DummyLocalGameLoop.getInstance().setNetworkConnection(clientConnection);
......@@ -36,6 +35,7 @@ public class GameStarter {
if (!DummyLocalGameLoop.getInstance().startedBefore())
DummyLocalGameLoop.getInstance().start();
//this is start and not run like in the DummyServer, because here we are dealing with a thread
ServerLoop dummyServerLoop=new ServerLoop(serverConnection);
dummyServerLoop.start();
//let the loop run now!
DummyLocalGameLoop.getInstance().startGame();
......
......@@ -4,8 +4,10 @@ import artificial_intelligence.AIControler;
import core.event.EmptyEvent;
import core.event.Event;
import core.event.MapInit;
import core.event.ToServerDeathEvent;
import core.gamestate.*;
import core.relayer.Relayers;
import graphics.graphical_abstraction.GraphicsMasterAbstraction;
import map_generation.map.Map;
import map_generation.map.MapGeneration;
import network.EndEvent;
......@@ -29,8 +31,17 @@ public class ServerLoop extends Thread {
this.networkConnection=serverConnection;
}
public synchronized NetworkConnection<NetworkObject> getNetworkConnection()
{
return networkConnection;
}
private static ServerLoop ourInstance = new ServerLoop();
public static ServerLoop getInstance() {
return ourInstance;
}
private ServerLoop() {
}
int cframe = 0;
private GameContent load(){
Map newMap= MapGeneration.mapGeneration(15, 20);
int playerNumber;
......@@ -76,6 +87,7 @@ public class ServerLoop extends Thread {
System.out.println("DummyServerLoop: Just received an EndEvent");
//this is so bad because if this thread sleeps for too long it's a disaster
cont=false;
networkConnection.initiateConnectionEnd();
}
}
if(cont == false)
......
......@@ -35,7 +35,9 @@ public abstract class GraphicsMasterAbstraction {
SINGLEPLAYER_GAME_CREATION,
MULTIPLAYER_CHARACTER_CHOICE,
SINGLEPLAYER_CHARACTER_CHOICE,
GAME_OVER}
GAME_OVER,
LOST_CONNECTION
}
//This map indicates to graphicsMaster which guiPanel is associated to each GUIState, it is filled in Graphicsmaster's constructor
protected HashMap<GUIStates, PanelAbstraction> mapGUIStatesToGUIPanel = new HashMap<>();
//The current state of the GUI
......
......@@ -38,12 +38,24 @@ public class GamePanelAbstractionController {
MyInputInterpreter.setMoveXRight(true);break;
case DOWN_ARROW:
MyInputInterpreter.setMoveYBottom(true);break;
case SPELL:
case ABILITY_1:
if(spellReleased){
MyInputInterpreter.tryToCastAbility(1);
spellReleased=false;
}
break;
case ABILITY_2:
if(spellReleased){
MyInputInterpreter.tryToCastAbility(2);
spellReleased=false;
}
break;
case ABILITY_3:
if(spellReleased){
MyInputInterpreter.tryToCastAbility(3);
spellReleased=false;
}
break;
case ATTACK:
if(attackReleased){
MyInputInterpreter.tryToCastAbility(0);
......@@ -70,7 +82,11 @@ public class GamePanelAbstractionController {
MyInputInterpreter.setMoveYBottom(false);break;
case ATTACK:
attackReleased=true;break;
case SPELL:
case ABILITY_1:
spellReleased=true;break;
case ABILITY_2:
spellReleased=true;break;
case ABILITY_3:
spellReleased=true;break;
default:
break;
......
......@@ -11,5 +11,6 @@ public interface LoungePanelAbstraction extends MenuPanelAbstraction {
public void chooseCharacterButtonAction();
public void backButtonAction();
public void playButtonAction();
}
......@@ -24,5 +24,6 @@ public class LoungePanelAbstractionController extends MenuPanelAbstractionContro
public void backButtonPressed(){
this.lounge_panel.backButtonAction();
}
public void playButtonPressed(){this.lounge_panel.playButtonAction();}
}
......@@ -6,6 +6,7 @@ import graphics.guiSkeleton.guiPanel.*;
import graphics.guiSkeleton.guiPanel.menuPanel.*;
import graphics.guiSkeleton.guiPanel.menuPanel.characterChoice.MultiPlayer_CharacterChoicePanel;
import graphics.guiSkeleton.guiPanel.menuPanel.characterChoice.SinglePlayer_CharacterChoicePanel;
import graphics.guiSkeleton.guiPanel.menuPanel.configuration.ConfigurationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameCreation.MultiPlayer_GameCreationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameCreation.SinglePlayer_GameCreationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameLoad.SinglePlayer_LoadGamePanel;
......@@ -54,6 +55,7 @@ public class GraphicsMaster extends GraphicsMasterAbstraction {
mapGUIStatesToGUIPanel.put(GUIStates.SINGLEPLAYER_GAME_CREATION, new SinglePlayer_GameCreationPanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.SINGLEPLAYER_CHARACTER_CHOICE, new SinglePlayer_CharacterChoicePanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.SINGLEPLAYER_LOADGAME, new SinglePlayer_LoadGamePanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.LOST_CONNECTION, new LostConnectionPanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.GAME_OVER, new GameOverPanel(this));
}
......
......@@ -17,6 +17,7 @@ public class Igniter_Main {
/** Initialise some packages to detect instantly uncorrect declarations **/
AbilityPackageInitialiser.initialisePackage();
EffectPackageInitialiser.initialisePackage();
System.out.println();
/** Launch the GUI (and thus the game) **/
GraphicsMaster.build();
......
package graphics.guiSkeleton;
import core.gamestate.Character;
import core.gamestate.GameContent;
import core.relayer.Relayer;
import graphics.guiSkeleton.guiPanel.GamePanel;
......@@ -11,6 +12,7 @@ import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.util.ArrayList;